<?php
//vim: ts=2 sw=2

include_once "db.php";

  class Migration {

    public static function instance() {
      static $inst = NULL;
      if ($inst === NULL) {
        $inst = new Migration();
      }
      return $inst;
    }

    private function __construct() {
    }

    public function run() {
      $db = DBConn::instance()->db();
      $user_version = intval($db->query("PRAGMA user_version")->fetchColumn());
      $this->applyMigrations($db, $user_version);
      $this->applyDataFixes($db);
    }

    protected function getMigrationFiles($user_version) {
      $result = array();
      $glob_pattern = build_file_path(cptBaseDir(), 'app', 'migrations', '*.php');
      $migrations = glob($glob_pattern);
      if (!is_array($migrations))
        return $result;

      foreach( $migrations as $mig ) {
        $parts = array();
        if (preg_match('/\/migrations\/([0-9]+)_[^\/]*.php$/', $mig, $parts)) {
          $order = intval($parts[1]);
          if ($order < $user_version)
            continue;
          $result[$order] = $mig;
        }
      }
      return $result;
    }

    protected function applyMigrations($db, $user_version) {
      $migrations = $this->getMigrationFiles($user_version);
      if (empty($migrations))
        return;

      ksort($migrations, SORT_NUMERIC);

      error_log('current user_version: ' . $user_version);
      error_log('find ' . count($migrations) . ' new db migrations, start to apply ...');
      $db->beginTransaction();
      foreach($migrations as $order => $path) {
        error_log('apply db migration: ' . $path . ' ...');
        include($path);
        $user_version = $order;
      }
      $user_version += 1;
      error_log('update $user_version to ' . $user_version);
      $db->query('PRAGMA user_version = ' . $user_version);
      $db->commit();
      error_log('db migration done.');
    }


    protected function applyDataFixes($db) {
      if (!$db)
        return;

      $flag_file = build_file_path(cptBaseDir(), 'RESET_ADMIN_PASSWORD');
      if (!file_exists($flag_file))
        return;
      
      error_log("start to reset password of 'admin' ...");
      $db->beginTransaction();
      $db->exec(<<<EOD
        UPDATE users SET salt = 'hNsq25IWKmRfSCOu', checksum = 'dc7b9f203aa5cf1bca33d5fc126cd783f98590e9' WHERE name = 'admin';
EOD
      );
      unlink($flag_file)
      $db->commit();
      error_log("password reset is done");
    }
  }

?>