<?php

namespace LakeDrops\DorgFlow;

use GitElephant\Repository;
use LakeDrops\Component\Composer\BaseHandler;
use Symfony\Component\Filesystem\Filesystem;

/**
 * Class Handler.
 *
 * @package LakeDrops\DorgFlow
 */
class Handler extends BaseHandler {

  /**
   * Post install/update event to prepare projects for development.
   */
  public function prepareDevProjects() {

    // We only do the fancy stuff for developers.
    if (!$this->isDevMode()) {
      return;
    }

    $options = $this->getOptions();
    if (empty($options['projects'])) {
      return;
    }

    $this->io->write('Dorgflow: Preparing drupol.org packages for development', TRUE);
    $installationManager = $this->composer->getInstallationManager();
    foreach ($options['projects'] as $project => $version) {
      $package = $this->getPackage($project);
      if ($package === NULL) {
        continue;
      }

      $path = $installationManager->getInstallPath($package);
      $this->io->write("- $project => $path", TRUE);
      $this->prepareWorkingDirectory($path, $project, $version);
    }
  }

  /**
   * Retrieve options from composer.json "extra" configuration.
   *
   * @return array
   *   The options.
   */
  protected function getOptions(): array {
    $extra = $this->composer->getPackage()->getExtra() + ['dorgflow' => []];
    return $extra['dorgflow'] + [
      'projects' => [],
    ];
  }

  /**
   * Prepare the working directory of a git based package for dorgflow.
   *
   * @param string $path
   *   Name of the working directory.
   * @param string $project
   *   Name of the project.
   * @param string $version
   *   Version to checkout.
   */
  protected function prepareWorkingDirectory($path, $project, $version) {
    list(, $projectname) = explode('/', $project);
    $uri = 'git@git.drupal.org:project/' . $projectname . '.git';

    // Git Clone the repository into the working directory.
    $repository = Repository::open($path);
    $repository->init();

    try {
      $origin = $repository->getRemote('origin', FALSE);
      if ($origin && $origin->getFetchURL() === $uri) {
        // Already setup correctly.
        return;
      }
    }
    catch (\Exception $ex) {
      // Ignore the exception and conitue setup.
    }

    $fs = new Filesystem();
    $fs->remove($path);
    $fs->mkdir($path);
    $repository->init();
    $repository->addRemote('origin', $uri);

    $repository->fetch();
    $repository->checkout($version);
    $repository->getCaller()->execute('branch --set-upstream-to origin/' . $version . ' ' . $version);
    $this->io->write('  - completed', TRUE);
  }

}