<?php

namespace Drupal\visitors\Commands;

use Drupal\Core\Database\Connection;
use Drupal\visitors\VisitorsTrackerInterface;
use Drupal\visitors\VisitorsUpgradeInterface;
use Drush\Commands\DrushCommands;
use Symfony\Component\Console\Helper\ProgressBar;

/**
 * Defines a Drush command.
 */
class VisitorsCommands extends DrushCommands {

  /**
   * The database connection.
   *
   * @var \Drupal\Core\Database\Connection
   */
  protected $database;

  /**
   * The visitors tracker.
   *
   * @var \Drupal\visitors\VisitorsTrackerInterface
   */
  protected $tracker;

  /**
   * The visitors upgrade.
   *
   * @var \Drupal\visitors\VisitorsUpgradeInterface
   */
  protected $upgrade;

  /**
   * Drush commands for rebuilding logs.
   *
   * @param \Drupal\Core\Database\Connection $database
   *   The database connection.
   * @param \Drupal\visitors\VisitorsTrackerInterface $tracker
   *   The visitors tracker.
   * @param \Drupal\visitors\VisitorsUpgradeInterface $upgrade
   *   The visitors upgrade.
   */
  public function __construct(
    Connection $database,
    VisitorsTrackerInterface $tracker,
    VisitorsUpgradeInterface $upgrade,
  ) {
    parent::__construct();

    $this->database = $database;
    $this->tracker = $tracker;
    $this->upgrade = $upgrade;
  }

  /**
   * Regenerates routes from path.
   *
   * @command visitors:upgrade
   * @aliases visitors-upgrade
   *
   * @usage drush visitors:upgrade
   *  Upgrade data from 8.x-2.x to 3.0.x.
   */
  public function upgrade() {

    $total = $this->getTotal();

    // Get the Symfony Console output interface.
    $output = $this->output();

    $progressBar = new ProgressBar($output, $total);
    $progressBar->setFormat('debug');
    $progressBar->start();

    do {
      $progressBar->advance();
      $this->doLog();
      $total -= 1;
    } while ($total > 0);

    // Finish the progress bar.
    $progressBar->finish();
    // Add a new line after the progress bar.
    $output->writeln('');

    // Output a completion message.
    $output->writeln('Task completed!');
  }

  /**
   * Migrate the page views.
   */
  protected function doLog() {
    $row = $this->getVisitorsRow();
    $id = $row['visitors_id'];
    $request_time = $row['visitors_date_time'];

    $visit = $this->upgrade->doVisitRecord($row);
    $log = $this->upgrade->doLogRecord($row);

    $visit['uid'] = $log['uid'] == 0 ? NULL : $log['uid'];

    $visit_id = $this->tracker->getVisitId($visit, $request_time);
    $log['visit_id'] = $visit_id;
    $event_id = $this->tracker->writeEvent($log);

    $this->tracker->updateVisit($visit_id, $event_id, $request_time, $visit['uid']);

    $this->upgrade->deleteVisitorsRow($id);
  }

  /**
   * Get the next visitors row.
   */
  protected function getVisitorsRow() {
    static $ids = [];

    if (empty($ids)) {
      $ids = $this->upgrade->getVisitorsRows(10000);
    }

    return (array) array_shift($ids);
  }

  /**
   * The total records to convert.
   */
  protected function getTotal() {
    $select = $this->database->select('visitors', 'v');
    $select->fields('v')
      ->isNotNull('v.visitor_id')
      ->countQuery();

    $count = $select->execute()->fetchField();

    return (int) $count;
  }

}
