<?php

if (!file_exists(LOG_DIR_PATH)) {
    mkdir(LOG_DIR_PATH, 0777, true);
}

$site_id = isset($_GET['site_id']) ? $_GET['site_id'] : '';

$dbpass='Kn2$gfEMSn';

// ----------------------------
// DB CONFIG FUNCTIONS
// ----------------------------
function getDbConfig($site_id, $dbpass) {
    if ($site_id === 'ourchive-org') {
        return [
            "host" => "10.151.0.92",
            "port" => "5432",
            "dbname" => "ourchive_writer_portal",
            "user" => "erspgadmin",
            "password" => $dbpass
        ];
    } else {
        return [
            "host" => "10.151.0.92",
            "port" => "5432",
            "dbname" => "hub_writer_portal",
            "user" => "erspgadmin",
            "password" => $dbpass
        ];
    }
}

function getDbConnection($site_id, $dbpass) {
    $config = getDbConfig($site_id, $dbpass);
    $conn = pg_connect("host={$config['host']} port={$config['port']} dbname={$config['dbname']} user={$config['user']} password={$config['password']}");
    if (!$conn) {
        throw new Exception("DB Connection Failed: " . pg_last_error());
    }
    return $conn;
}

function closeDbConnection($conn) {
    if ($conn) {
        pg_close($conn);
    }
}

function runQuery($site_id, $dbpass, $sql) {
    $conn = getDbConnection($site_id, $dbpass);
    $result = pg_query($conn, $sql);
    if (!$result) {
        $error = pg_last_error($conn);
        closeDbConnection($conn);
        throw new Exception("Query Error: " . $error);
    }
    closeDbConnection($conn);
    return $result;
}

function normalizePayload($response) {
    if (isset($response['object_kind']) && $response['object_kind'] === 'merge_request') {
        $mr = $response['object_attributes'] ?? [];

        if (isset($response['project'])) {
            $response['repository']['git_ssh_url'] = $response['project']['git_ssh_url'] ?? '';
            if (empty($response['repository']['name'])) {
                $response['repository']['name'] = $response['project']['name'] ?? '';
            }
        }

        $response['after'] = $mr['merge_commit_sha'] 
            ?? ($mr['last_commit']['id'] ?? '');
    }

    return $response;
}

// ----------------------------
// GITLAB PAYLOAD DATA
// ----------------------------
$payload = file_get_contents('php://input');

if (isset($payload) && $payload) {
    $response = json_decode($payload, true);	
    $response = normalizePayload($response);

    $sql = "INSERT INTO webhook_response(repository, webhook_response, webhook_status) 
            VALUES ('".$response['repository']['name']."','".json_encode($response)."','pending')";
    runQuery($site_id, $dbpass, $sql);

    run_webhook($site_id, $dbpass, $response );
}

// ----------------------------
// RUN WEBHOOK PROCESS
// ----------------------------
function run_webhook($site_id, $dbpass, $response) {

    while (true) {
        // Check if any webhook already running
        $query = "SELECT * FROM webhook_response WHERE repository = '".$response['repository']['name']."' AND webhook_status = 'running' ORDER BY datetime DESC LIMIT 1";
        $running_query = runQuery($site_id, $dbpass, $query);
        $running_row   = pg_fetch_assoc($running_query);

        if ($running_row) {
            return true;
        }

        // Get pending webhook
        $query = "SELECT * FROM webhook_response WHERE repository = '".$response['repository']['name']."' AND webhook_status = 'pending' ORDER BY datetime DESC LIMIT 1";
        $webhook_query = runQuery($site_id, $dbpass, $query);
        $webhook_row   = pg_fetch_assoc($webhook_query);

        if (!$webhook_row) {
            return true; 
        }

        $response_data = json_decode($webhook_row['webhook_response'], true);

        $filepath = LOG_DIR_PATH . $response_data['repository']['name'].'-hook-log-' . 
                    $response_data["after"] .'-' . date('Y-m-d') . '.php';

        $message  = PHP_EOL ;
        $message .= '===================' .PHP_EOL;
        $message .=  date('Y-m-d H:i:s') . PHP_EOL;
        $message .= '===================' .PHP_EOL;
        $message .= 'GIT RESPONSE -->' . $webhook_row['webhook_response'] . PHP_EOL;
        logWrite($filepath, $message);

        runQuery($site_id, $dbpass, "UPDATE webhook_response SET webhook_status = 'running' WHERE id = " . $webhook_row['id']); 

        // -----------------------------
        // GITLAB TASKS
        // -----------------------------
        $repo_ssh_url = $response_data['repository']['git_ssh_url'];
        $repo   = $response_data['repository']['name'];
        $branch = "master";
        $source = SOURCE_DIR_PATH;
        $rmpath = $source.$repo;

        $gitDataArray = [$repo, $branch, $repo_ssh_url, $source, $repo, $rmpath];
        logWrite($filepath, 'GIT DATA-->' . PHP_EOL . print_r($gitDataArray, true));

        if (file_exists($rmpath)) {
            exec("rm -rf $rmpath 2>&1", $removeoutput);
            logWrite($filepath, "rm $rmpath -->" . json_encode($removeoutput) . PHP_EOL);
        }

        exec("cd $source && git clone $repo_ssh_url 2>&1", $cloneoutput);
        logWrite($filepath, "GIT CLONE --> " . print_r($cloneoutput, true) . PHP_EOL);

        chdir($rmpath);

        // GET rakefile from DB
        $sql = "SELECT * FROM article_github WHERE REPLACE(gitlab_repo,'https://amgit.altametrics.com/web-development-team/','') = '$repo'";
        $result = runQuery($site_id, $dbpass, $sql);
        $row = pg_fetch_assoc($result);

        if ($row && $row['rakefile']) {
            if (file_exists("$rmpath/rakefile")) {
                exec("rm $rmpath/rakefile 2>&1", $rakeoutput);
                logWrite($filepath, "rm $rmpath/rakefile -->" . json_encode($rakeoutput) . PHP_EOL);
            }
            rakeWrite("$rmpath/rakefile.rb", $row['rakefile']);
        }

        if (file_exists("$rmpath/_site/")) {
            exec("rm -rf $rmpath/_site 2>&1", $rmsiteoutput);
            logWrite($filepath, "rm $rmpath/_site -->" . json_encode($rmsiteoutput) . PHP_EOL);
        }

        if (file_exists("$rmpath/Gemfile.lock")) {
            exec("rm $rmpath/Gemfile.lock 2>&1", $rmoutput);
            logWrite($filepath, "rm $rmpath/Gemfile.lock -->" . json_encode($rmoutput) . PHP_EOL);
        }

        // Rake build run
        $pramArray = [$rmpath, $repo, $response_data["after"]];
        $pram = implode(' ', $pramArray);

        logWrite($filepath, 'Rakeprod Param --> ' . $pram . PHP_EOL);
        $result = exec(SOURCE_DIR_PATH . 'rakeprod.sh ' . $pram, $retval);
        logWrite($filepath, 'result --> ' . json_encode($result) . PHP_EOL);

        if ($result) {
            $date = date('Y-m-d h:i:s', time());
            $rep_udate_query = "UPDATE wp_sites  SET site_datetime_last_deployed = '$date' WHERE site_github_repo_id = '$repo'";
            $rep_udate_result = runQuery($site_id, $dbpass, $rep_udate_query);
            if (!$rep_udate_result) {
                logWrite($filepath, "PG ERROR: query failed -->" . $rep_udate_query . PHP_EOL);
            } else {
                logWrite($filepath, "Update Successful --> " . $rep_udate_query . PHP_EOL);
            }
        }
        // UPDATE build publish
        $query = "UPDATE webhook_response SET webhook_status = 'publish' WHERE datetime <= '" . $webhook_row['datetime'] . "'";
        $update_webhook = runQuery($site_id, $dbpass, $query);
        if (!$update_webhook) {
            logWrite($filepath, "PG ERROR: query failed" . PHP_EOL);
        } else {
            logWrite($filepath, "Webhook Updated to publish" . PHP_EOL);
        }

        logWrite($filepath, PHP_EOL . 'WEBSITE IS LIVE NOW' . PHP_EOL);
        sleep(5);
    }
}

function logWrite($filepath, $message){
    if (!file_exists($filepath)) {
        $message = "<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed'); ?>" . PHP_EOL . $message;
    }
    if (!$fp = fopen($filepath, 'ab')) {
        return FALSE;
    }
    flock($fp, LOCK_EX);
    fwrite($fp, $message);
    flock($fp, LOCK_UN);
    fclose($fp);
}

function rakeWrite($filepath, $message){
    if (!$fp = fopen($filepath, 'w')) {
        return FALSE;
    }
    flock($fp, LOCK_EX);
    fwrite($fp, $message);
    flock($fp, LOCK_UN);
    fclose($fp);
}
?>
