<?php
namespace nur\tools\compctl;

use nur\b\IllegalAccessException;
use nur\cli\Application;
use nur\msg;
use nur\path;
use nur\yaml;

class CompctlApp extends Application {
  const ACTION_INIT = 10, ACTION_INFOS = 20;
  const ACTION_SYNC = 30;
  const ACTION_SYNC_ALL = -1, ACTION_SYNC_COMPOSER = 1, ACTION_SYNC_UPDATE_APPS = 2, ACTION_SYNC_DOCKER_COMPOSE = 4, ACTION_SYNC_IDEA_PROJECT = 8;

  const ARGS = [
    "merge" => parent::ARGS,
    "purpose" => "gestion du fichier composer.json",
    ["-0", "--init", "name" => "action", "value" => self::ACTION_INIT,
      "help" => "Créer une configuration si elle n'existe pas déjà",
    ],
    ["--infos", "name" => "action", "value" => self::ACTION_INFOS,
      "help" => "Afficher la configuration",
    ],
    ["group",
      ["-s", "--sync", "name" => "action", "value" => self::ACTION_SYNC,
        "help" => "Synchroniser les fichier à partir de la configuration",
      ],
      ["-a", "--sa", "--sync-all", "name" => "action_sync", "value" => self::ACTION_SYNC_ALL],
      ["--sc", "--sync-composer", "name" => "action_sync", "value" => self::ACTION_SYNC_COMPOSER],
      ["--su", "--sync-update-apps", "name" => "action_sync", "value" => self::ACTION_SYNC_UPDATE_APPS],
      ["--sd", "--sync-docker-compose", "name" => "action_sync", "value" => self::ACTION_SYNC_DOCKER_COMPOSE],
      ["--sp", "--sync-idea-project", "name" => "action_sync", "value" => self::ACTION_SYNC_IDEA_PROJECT],
    ],
    ["-d", "--projdir", "args" => "dir",
      "help" => "Spécifier le répertoire du projet. Par défaut, chercher à partir du répertoire courant",
    ],
    ["-b", "--branch", "args" => 1,
      "help" => "Utiliser la configuration associée à la branche spécifiée. Par défaut, utiliser la branche courante",
    ],
    ["-i", "--inplace", "value" => true,
      "help" => "modifier le fichier en place, au lieu d'afficher le nouveau contenu",
    ],
  ];

  protected $action = self::ACTION_INFOS;
  protected $actionSync = 0;
  protected $projdir, $branch, $inplace = false;

  protected $args;

  protected function checkConfigFile(string $configFile, ?string $projdir=null): void {
    if (!file_exists($configFile)) {
      $message = "aucune configuration n'a été trouvée";
      if ($projdir) $message = path::ppath($projdir) . ": $message";
      msg::warning($message);
      self::exit(1);
    }
  }

  function main() {
    git::setup();
    [$projdir, $composerFile, $configFile] = ut::resolve_projdir($this->projdir);
    [$gitdir, $branch] = ut::resolve_branch($this->branch, $projdir);

    if ($this->action == self::ACTION_INIT) {
      $composer = new ComposerFile($composerFile, $projdir);
      $config = $composer->initConfig($configFile);
      if ($config === null) return false;
      yaml::dump($config->getv());

    } else {
      $inplace = $this->inplace;
      $config = new ConfigFile($configFile, $projdir);
      switch ($this->action) {
      case self::ACTION_INFOS:
        yaml::dump([
          "projdir" => $projdir,
          "composer_file" => $composerFile,
          "config_file" => $configFile,
          "git_dir" => $gitdir,
          "branch" => $branch,
          "config" => $config->getv(),
        ]);
        break;
      case self::ACTION_SYNC:
        $actionSync = $this->actionSync;
        if ($actionSync == 0) $actionSync = self::ACTION_SYNC_COMPOSER;
        $synced = false;
        if ($actionSync & self::ACTION_SYNC_COMPOSER) {
          $dest = new ComposerFile($composerFile, $projdir);
          $synced |= $dest->sync($config, $branch, $inplace);
        }
        if ($actionSync & self::ACTION_SYNC_UPDATE_APPS) {
          $dest = new UpdateAppsFile();
          $synced |= $dest->sync($config, $branch, $inplace);
        }
        if ($actionSync & self::ACTION_SYNC_DOCKER_COMPOSE) {
          $dest = new DockerComposeFile();
          $synced |= $dest->sync($config, $branch, $inplace);
        }
        if ($actionSync & self::ACTION_SYNC_IDEA_PROJECT) {
          $dest = new IdeaProject();
          $synced |= $dest->sync($config, $branch, $inplace);
        }
        return $synced;
      default:
        throw IllegalAccessException::unexpected_state("action non implémentée");
      }
    }
    return 0;
  }
}
