<?php    
    # Abort if the request is NOT a POST
    if ($_SERVER['REQUEST_METHOD'] !== 'POST') { return; }

    # Set the timezone to NYC
    date_default_timezone_set('America/New_York');

    //	Make sure we have the accept (json) header
	$allheaders = getallheaders();
	if (!isset($allheaders['Accept'])) { echo json_encode(array('msg' => 'Accept header not set', 'success' => false), JSON_PRETTY_PRINT); return; }
    if (($allheaders['Accept'] != 'application/json')) { return; }

    # Make sure we have our apikey
    if (!isset($allheaders['X-Api-Key'])) { echo json_encode(array('error' => 'API Key is not present', 'success' => false), JSON_PRETTY_PRINT); return; }
    if (($allheaders['X-Api-Key'] != 'e068ee4e-9be7-4226-9132-661c6ca9dec2')) { return; }

    # If Post is empty
    if (empty($_POST)) { echo json_encode(array('error' => 'POST is empty', 'success' => false), JSON_PRETTY_PRINT); return; }

    # Assign _POST to data for easier of reading
    $data = $_POST;
    if (!isset($data['cmd'])) { echo json_encode(array('error' => 'Invalid data posted', 'success' => false), JSON_PRETTY_PRINT); return; }

    # Define our database
    $database = new SQLite3('./database/5PhFPpmCCzR3.db');
    $database->enableExceptions(true);
    perform_database_checks($database);

    # Depending on the command, we will take appropriat eactions
    $command = $data['cmd'];
    if ($command == "get_computer_name") {
        # If we are missing the serial number, return a random name
        if (!isset($data['serial_number'])) { 
            echo json_encode(array('computer_name' => generate_random_string(), 'success' => true), JSON_PRETTY_PRINT); 
            return;
        }

        # Let's search the database for the serial
        $computer_name_from_database = get_computer_name($database, $data['serial_number']);

        # If we don't have a name, return the serial 
        $computer_name = strlen($computer_name_from_database) > 3 ? $computer_name_from_database : 'KIPP-' . $data['serial_number'];
        echo json_encode(array('computer_name' => $computer_name, 'success' => true), JSON_PRETTY_PRINT);
        return;
    } elseif ($command == "set_computer_name") {
        # We need to have a few things, serial number and computer name
        if (!isset($data['serial_number']) || !isset($data['computer_name'])) {
            echo json_encode(array('error' => 'Invalid data posted', 'success' => false), JSON_PRETTY_PRINT); 
            return;
        }

        # Let's pull the current name (if any)
        $computer_name_from_database = get_computer_name($database, $data['serial_number']);

        # Only add it if the name does not match
        if ($computer_name_from_database != trim(strtoupper($data['computer_name']))) { 
            set_computer_name($database, $data['serial_number'], $data['computer_name'], $data['device_type']);
        }

        # done
        echo json_encode(array('success' => true), JSON_PRETTY_PRINT); 
        return; 
    } elseif ($command == "get_gc") {
        # Define the username / password
        $username = "viewer";
        $password = strrev("ZdUhgJL89fB4kHMhFFejETkgr7rVWqs8");

        # Make it into an array
        $cred = array('username' => $username, 'password' => $password);

        # Json encode it
        $json_string = json_encode($cred);

        # base64 and reverse it
        $json_string_reverse = base64_encode(strrev(base64_encode($json_string)));

        # send it
        echo json_encode(array('success' => true, 'data' => $json_string_reverse));

        return;
    }


    
    // close the database
    $database->close();
    /********************************* FUNCTIONS *********************************/

    /*
        @function:      perform_database_checks
        @params:        database
        @return:        none
        @purpose:       create, modify, etc the database file
    */
    function perform_database_checks($database) {

        // Create the initial database
        $database->query('CREATE TABLE IF NOT EXISTS "computer_names" ("serial_number"	TEXT NOT NULL UNIQUE, "computer_name"	TEXT NOT NULL, PRIMARY KEY("serial_number") );');
        $database->query('CREATE TABLE IF NOT EXISTS "google" ("serial_number"	TEXT NOT NULL UNIQUE, "computer_name"	TEXT NOT NULL, "device_type"    TEXT, PRIMARY KEY("serial_number") );');
        $database->query('CREATE TABLE IF NOT EXISTS "logs" ("id"	INTEGER NOT NULL UNIQUE, "ip_address"	TEXT NOT NULL, "note"	INTEGER NOT NULL, PRIMARY KEY("id" AUTOINCREMENT) );');
    }

    /*
        @function:      get_computer_name
        @params:        database, serial_number
        @return:        computer name
        @purpose:       gets the name from the atabae
    */
    function get_computer_name($database, $serial_number) {
        // build the statement
        $sql = "SELECT computer_name FROM computer_names WHERE serial_number=:searchvalue";
        $statement = $database->prepare($sql);
        $statement->bindValue(':searchvalue', SQLite3::escapeString(trim(strtoupper($serial_number))), SQLITE3_TEXT);

        # execute
        $results = $statement->execute()->fetchArray(SQLITE3_ASSOC);

        return ($results['computer_name']);
    }

    /*
        @function:      set_computer_name
        @params:        database, serial_number, computer_name
        @return:        none
        @purpose:       create, modify, etc the database file
    */
    function set_computer_name($database, $serial_number, $computer_name, $device_type) {
        // build the statement
        // $sql = "INSERT OR REPLACE INTO computer_names (serial_number, computer_name) VALUES (:serial_number, :computer_name) WHERE serial_number = :serial_number";
        $sql = "INSERT INTO computer_names (serial_number, computer_name) VALUES (:serial_number, :computer_name) ON CONFLICT (serial_number) DO UPDATE SET computer_name=:computer_name";
        $statement = $database->prepare($sql);
        $statement->bindValue(':serial_number', SQLite3::escapeString(trim(strtoupper($serial_number))), SQLITE3_TEXT);
        $statement->bindValue(':computer_name', SQLite3::escapeString(trim(strtoupper($computer_name))), SQLITE3_TEXT);
        
        // # execute
        $results = $statement->execute();

        // build the statement
        $sql = "INSERT INTO google (serial_number, computer_name, device_type) VALUES (:serial_number, :computer_name, :device_type) ON CONFLICT (serial_number) DO UPDATE SET computer_name=:computer_name";
        $statement = $database->prepare($sql);
        $statement->bindValue(':serial_number',     SQLite3::escapeString(trim(strtoupper($serial_number))), SQLITE3_TEXT);
        $statement->bindValue(':computer_name',     SQLite3::escapeString(trim(strtoupper($computer_name))), SQLITE3_TEXT);
        $statement->bindValue(':device_type',       SQLite3::escapeString(trim(strtoupper($device_type))), SQLITE3_TEXT);
        
        
        // # execute
        $results = $statement->execute();

        return;
    }

    /*
        @function:      is_base64
        @params:        $string
        @return:        true/false
        @purpose:       checks to see if a string is base64 or not
    */
    function is_base64($string){
	    // Check if there are valid base64 characters
	    if (!preg_match('/^[a-zA-Z0-9\/\r\n+]*={0,2}$/', $string)) { return false; }

	    // Decode the string in strict mode and check the results
	    $decoded = base64_decode($string, true);
	    if(false === $decoded) { return false; }

	    // Encode the string again
	    if(base64_encode($decoded) != $string) { return false; }

        // The checks to see if it can be decoded / encoded back to itself went through succesfully, safe to assume it is base64
	    return true;
    }

    /*
        @funtion:   get_public_ip
        @params:    none
        @return:    string (ip address)
        @purpose:   return the public ip address of the request
    */
    function get_public_ip() {
        //	Get the IP Address
        $ip = null;
        if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
            $ip = $_SERVER['HTTP_CLIENT_IP'];
        } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
        } else {
            $ip = $_SERVER['REMOTE_ADDR'];
        }

        //  retur the ip address
        return $ip;
    }

    /*
        @function:  generate_random_string
        @params:    none
        @return:    string
        @purpose:   generates a random string
    */
    function generate_random_string($length = 12) {
    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $charactersLength = strlen($characters);
    $randomString = '';

    for ($i = 0; $i < $length; $i++) {
        $randomString .= $characters[random_int(0, $charactersLength - 1)];
    }

    return $randomString;
}


?>
