<?php
 if(php_sapi_name() != "cli")
  exit("This script is intended to be run from the CLI\n");

 if(!is_dir("Indexers"))
  exit("Run from the git root (Indexers/ not found in CWD)\n");

 $DEFSDIR = "Indexers/definitions/v11";
 $TRACKERSFILE = "trackers.json";
 $CREDTYPESET = ["text" => true, "password" => true]; // settings field types that become credentials
 $SECRETTYPESET = ["private" => true, "semi-private" => true]; // tracker types that carry a credentials block

 echo "Updating source\n";
 $firsttimestart = microtime(true);

 exec("git -C Indexers pull 2>&1", $gitout, $gitcode);
 foreach($gitout as $line)
  echo " $line\n";
 if($gitcode != 0)
  echo "git pull returned $gitcode, using current checkout\n";

 $exectime = round((microtime(true) - $firsttimestart) * 1000);
 echo "Execution time: $exectime ms\n\n";
 echo "Loading previous credentials\n";
 $timestart = microtime(true);

 $oldcreds = [];
 if(file_exists($TRACKERSFILE)) {
  $old = json_decode(file_get_contents($TRACKERSFILE), true);
  if(is_array($old))
   foreach($old as $id => $entry)
    if(isset($entry["credentials"]))
     $oldcreds[$id] = $entry["credentials"];
 }
 echo "Trackers with stored credentials: ".count($oldcreds)."\n";

 $exectime = round((microtime(true) - $timestart) * 1000);
 echo "Execution time: $exectime ms\n\n";
 echo "Parsing and merging definitions\n";
 $timestart = microtime(true);

 $files = glob("$DEFSDIR/*.yml");
 $trackers = [];
 $failed = [];
 $statstypes = [];
 $nbsecret = 0;
 $nbfilled = 0;
 foreach($files as $file) {
  $def = @yaml_parse_file($file);
  if($def === false || !isset($def["id"]) || !isset($def["type"])) {
   $failed[] = basename($file);
   continue;
  }

  $id = $def["id"];
  $type = $def["type"];

  if(isset($statstypes[$type]))
   $statstypes[$type]++;
  else
   $statstypes[$type] = 1;

  if(!isset($SECRETTYPESET[$type])) {
   $trackers[$id] = $def;
   continue;
  }

  // derive the credential fields this tracker declares in its settings block
  $template = [];
  if(isset($def["settings"]))
   foreach($def["settings"] as $setting)
    if(isset($setting["name"], $setting["type"]) && isset($CREDTYPESET[$setting["type"]]))
     $template[$setting["name"]] = "";

  // keep previously entered values, leave new fields blank
  $creds = $template;
  if(isset($oldcreds[$id]))
   foreach($template as $name => $blank)
    if(isset($oldcreds[$id][$name]) && $oldcreds[$id][$name] != "")
     $creds[$name] = $oldcreds[$id][$name];

  $nbsecret++;
  foreach($creds as $value)
   if($value != "") {
    $nbfilled++;
    break;
   }

  $trackers[$id] = ["credentials" => $creds] + $def;
 }

 echo "Definitions parsed: ".count($trackers)."\n";
 echo "Parse failures: ".count($failed)."\n";
 foreach($failed as $f)
  echo "Failed to parse: \"$f\"\n";

 $exectime = round((microtime(true) - $timestart) * 1000);
 echo "Execution time: $exectime ms\n\n";
 echo "Writing output\n";
 $timestart = microtime(true);

 ksort($trackers);
 file_put_contents($TRACKERSFILE, json_encode($trackers, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));

 echo "Output size: ".round(filesize($TRACKERSFILE) / 1000)." KB\n";

 $exectime = round((microtime(true) - $timestart) * 1000);
 echo "Execution time: $exectime ms\n\n";

 echo "Types\n";
 arsort($statstypes);
 foreach($statstypes as $key => $value)
  echo "$key $value\n";
 echo "\n";

 echo "Credentials\n";
 echo "Filled: $nbfilled\n";
 echo "Blank: ".($nbsecret - $nbfilled)."\n";

 $exectime = round((microtime(true) - $firsttimestart) * 1000);
 echo "Total execution time: $exectime ms\n";
?>
