<?php

class GeminiJob extends Job {

	public $docid;

	public function __construct($docid, $source="unknown") {
		parent::__construct($source);
		$this->docid = $docid;
	}

	public function run() {

		$pdf = false;

       $subs = [
            "Installation and Operating Information",
            "Installation and Configuration",
            "Installing and Getting Started",
            "Installation/Operator's Manual",
            "Installation/Operator's Guide",
            "Programmer's Reference Guide",
			"Field Maintenance Print Set",
            "Illustrated Parts Breakdown",
            "Installation/Owner's Guide",
            "Installation Information",
            "Installation/User Guide",
            "User Documentation Kit",
            "Programmer Information",
            "Technical Description",
            "Operator Information",
            "Configuration Guide",
            "Upgrade Information",
            "Installation Manual",
            "Service Information",
            "Installation Guide",
			"Programming Manual",
            "Maintenance Manual",
            "Maintenance Guide",
            "Technical Summary",
            "Operator's Guide",
            "System Reference",
            "User Information",
            "Technical Manual",
            "Language Manual",
            "Service Manual",
            "Service Guide",
            "Read Me First",
            "Owner's Guide",
            "Release Notes",
            "Options Guide",
            "Users' Manual",
            "User's Manual",
            "HiTest Notes",
            "User's Guide",
            "Design Guide",
            "User Manual",
            "User Guide",

        ];

		$doc = new Document($this->docid);

		$minsize = 999999999999999;

		foreach ($doc->revisions as $r) {
			$p = new PDF($r->path() . "/doc.pdf");
			if ($p->size() < $minsize) {
				$minsize = $p->size();
				$rev = $r;
				$pdf = $p;
			}
		}

		if (!$pdf) {
			$this->fail();
			return;
		}

		$this->status("Processing document with Gemini");
		try {
			$gemini = new Gemini();
			$gemini->upload_callback([$this, "uploadcb"]);
			$gemini->process_callback([$this, "processcb"]);
			$lines = $gemini->geminiOverview($pdf);
		} catch (Exception $e) {
			$this->status($e->getMessage());
			if ($e->getmessage() == "The request timed out. Please try again.") {
				$this->retry();
			} else if ($e->getmessage() == "HTTP Error 0 requesting AI assistance") {
				$this->retry();
			} else {
				$this->fail();
			}
			return;
		}

		$this->status("Postprocessing returned data");
		$ld = explode("\n", $lines);
		if (preg_match('/^\{(.*)\}$/', trim($ld[0]), $m)) {
			$title = trim($m[1]);

			$title = str_replace("’", "'", $title);

			$newsub = "";
			$newsubsub = "";


			$b = explode(":", $title);
			if (count($b) > 1) {
				$title = trim(array_shift($b));
				$newsub = trim(array_shift($b));
				$newsubsub = implode(": ", $b);
			}

			if ($newsub == "") {
				foreach ($subs as $sub) {
					if (str_ends_with($title, $sub)) {
						$newsub = $sub;
						$title = substr($title, 0, 0 - (strlen($sub) + 1));
						break;
					}
				}
			}
		   $doc->title = $title;
			$doc->subtitle = $newsub;
			$doc->subsubtitle = $newsubsub;

			array_shift($ld);
			if (trim($ld[0]) == "") {
				array_shift($ld);
			}
		}
		if (preg_match('/^\[(.*)\]$/', trim($ld[0]), $m)) {

			$iid = IDMatch::find_docid($this->cleanup($m[1]));

			if ($iid) {
				$doc->internal_id = $iid[0];
			}
			array_shift($ld);
		}
		$doc->overview = implode("\n", $ld);

		$doc->save();
/*
		$db = DB::getInstance();

		$q = $db->query("
			select
				product.id as id,
				locate(product.title, document.title) as wordoffset
			from
				product,
				document
			where
				locate(product.title, document.title) > 0 and
				document.id = :id and
				length(product.title) > 3
			order by
				length(product.title) desc
			limit 0,1
		", ["id" => $doc->id]);

	   if ($r = $db->nextRecord($q)) {
			$d = new DocProduct();
			$d->document = $doc->id;
			$d->product = $r->id;
			$d->save();
		} else {
			$q = $db->query("
				select
					product.id as id,
					locate(product.title, document.overview) as wordoffset
				from
					product,
					document
				where
					locate(product.title, document.overview) > 0 and
					locate(product.title, document.overview) < 300 and
					document.id = :id and
					length(product.title) > 3
				order by
					length(product.title) desc
				limit 0,1
			", ["id" => $doc->id]);

			if ($r = $db->nextRecord($q)) {
				$d = new DocProduct();
				$d->document = $doc->id;
				$d->product = $r->id;
				$d->save();
			}
		}
*/

		$this->status("Finished");
	}


	public function uploadcb($percent) {
		$this->status("Uploading: " . $percent . "% complete");
	}

	public function processcb($message) {
		$this->status($message);
	}

	function cleanup($txt) {
		$txt = str_replace("Ø", "0", $txt);
		$txt = str_replace(".", " ", $txt);
		return $txt;
	}
}
