<?php

    // Connect to a server, also test connection_aborted
    try {
        require_once realpath(__DIR__ . '/output_base.php');
    } catch (\Throwable $e) {			// php 7
        die('Error:' . $e->getMessage() . ' in ' . $e->getFile() . ' at line ' . $e->getLine() . ' [25]');
    }

class Connection {

	private $DATA;
	protected $timeout;
	// while this is enabled, crontab cannot run - ownership problem:
	protected $logging = '/home/phil/connection.txt';
	//protected $logging = FALSE;
    protected $output_transport;        // class for returning process output to the user.
	private $lp = FALSE;
	private $x_script;
	public $error_output;

    public function __construct() {
        # attach the appropriate `output_base` class
        $this->output_transport = \output_base::Transport();
    }

	public function ServerData() {
		if (func_num_args()) {
			$this->DATA = func_get_arg(0);
			return $this;
		}
		return $this->DATA;
	}
	
	public function timeout() {
		if (func_num_args()) {
			$this->timeout = func_get_arg(0);
			return $this;
		}
		return $this->timeout;
	}

	public function LogFilename() {
		if (func_num_args()) {
			$this->logging = func_get_arg(0);
			return $this;
		}
		return $this->logging;
	}
	
	public function getServerId() {
		return $this->DATA->server_id;
	}

	public function Log($message) {
		if ($this->logging !== FALSE) {
			if ($this->lp === FALSE) $this->lp = fopen($this->logging, 'a');
			$dt = date('Y-m-d H:i:s');
			if (is_resource($this->lp)) {
				fwrite($this->lp, "$dt: {$message}\n");
			}
		}
	}
	
	public function LogOutput($remotecommand) {
		if (is_resource($this->lp)) {
			$output = $remotecommand->output;
			if (substr($output, 0, 2) == "\x1f\x8b") {
				fwrite($this->lp, "(gzipped output)\n");
				$output = gzdecode($output);
			}
			fwrite($this->lp, "\n\n{$output}\n\n");
			if (trim($remotecommand->error) != '') {
				fwrite($this->lp, "\n\nSTDERR:\n{$remotecommand->error}\n\n");
			}
		}
	}

	// if logged in (and FULL), perform checks:
	//		uptime
	//		32/64bit
	//		webserver used:  apache, httpd, nginx
	//		mysql used. socket, version, etc/?
	//		... and any other checks requested by other modules

	public function GetServerStatus() {
		$sequence = hook_list('agent.linux');
		foreach($sequence as $priority => $items) {
			foreach($items as $item) {
				$item->connection($this);
                $this->Execute($item);
			}
		}
	}
    
    public function Execute($remote) {
        // this must be overridden.
    }

	public function ExecuteScript($script, $user, $decompress = FALSE) {
		$this->x_script = $script;
		$remote = remote_script([$this, '__generic_script'], NULL, $user, $this);
		$this->timeout(600);		// this may take a while
        $j = $this->Execute($remote);
		$this->timeout(15);
		$this->error_output = $remote->error;
		$output = $remote->output;
		if ($decompress && substr($output, 0, 2) == "\x1f\x8b") {
			$output = gzdecode($output);
		}
        // j = -3: script not executed. 
		return ($j == -3) ? FALSE : $output;
	}
	
	function __generic_script($remote) {
		return $this->x_script;
	}

	public function UploadFile($filename, $content) {
	}
	
	// upload the file, return commands to execute and delete target file
	protected function prepareScript($content, $user) {
		$content = str_replace("\r\n", "\n", $content);
		$filename = '/tmp/pkp' . mt_rand(100000,999999);
		$this->Log("\n\nPUT: $filename\n\n$content\n");
		$this->UploadFile($filename, $content);
        $executableCommand = $filename;
        // We don't need to do anything with the output - so direct it to seashells or eggshell.
        if ($this->output_transport->isBackground()) {
            $executableCommand = $this->output_transport->prepareCommand($executableCommand);
            if ($executableCommand === NULL) {      // no command to be executed - assume already done
                return [ NULL, NULL ];
            }
        }
		if ($user != 'root') {
			$prefix = "chmod 755 $filename; chown $user:$user $filename; ";
			$command = "$executableCommand; rm $filename";
		} else {
            $prefix = '';
			$command = "chmod 755 $filename; $executableCommand; rm $filename";
		}
		return [$prefix, $command];
	}
	
	// log in
	public function EstablishConnection() {
		
	}

}