<?php
putenv("PATH=/usr/sbin:/usr/bin:/sbin:/bin");


log_msg("PHP running as user: " . get_current_user());
log_msg("PHP effective UID: " . posix_geteuid());

/**
 * SYSTAPP MODE — Enterprise Domain Creation Pipeline
 * Ownership: appsyst:appsyst
 * DNSSEC: Full signing
 */

$logDir  = '/home/logs';
$logFile = $logDir . '/domain_create.log';

if (!is_dir($logDir)) {
    mkdir($logDir, 0755, true);
}
if (!file_exists($logFile)) {
    touch($logFile);
    chown($logFile, 'apache');
    chgrp($logFile, 'apache');
    chmod($logFile, 0664);
}

function log_msg(string $msg) {
    global $logFile;
    $line = '[' . date('Y-m-d H:i:s') . '] ' . $msg . "\n";
    file_put_contents($logFile, $line, FILE_APPEND);
}

require_once __DIR__ . '/../lib/serial.php';

// =========================
// CONFIG
// =========================
$defaultIPv4      = '87.99.138.216';
$namedZoneDir     = '/var/named/chroot/var/named';
$dnssecKeyRoot    = "$namedZoneDir/keys";
$opendkimKeyRoot  = '/etc/opendkim/keys';
$opendkimKeyTable = '/etc/opendkim/KeyTable';
$opendkimSignTable= '/etc/opendkim/SigningTable';
$opendkimTrusted  = '/etc/opendkim/TrustedHosts';
$aliasesFile      = '/etc/aliases';
$namedConf        = '/etc/named.conf';
$ownerUser        = 'appsyst';
$ownerGroup       = 'appsyst';

// =========================
// INPUT
// =========================
$domain = trim($_POST['domain'] ?? '');
$ipv4   = trim($_POST['ipv4'] ?? $defaultIPv4);

if ($domain === '' || !preg_match('/^[a-z0-9.-]+\.[a-z]{2,}$/', $domain)) {
    log_msg("Invalid domain: '$domain'");
    echo json_encode(['ok' => false, 'error' => 'Invalid domain']);
    exit;
}

log_msg("Starting provisioning for domain: $domain");

// =========================
// SERIAL
// =========================
function generate_serial(): string {
    return date('Ymd') . '01';
}

$serial = generate_serial();

// =========================
// DKIM KEY GENERATION
// =========================
function generate_dkim_keys(string $domain, string $root): array {
    $keyDir = "$root/$domain";

    if (!is_dir($keyDir)) {
        mkdir($keyDir, 0770, true);
        chown($keyDir, 'opendkim');
        chgrp($keyDir, 'opendkim');
        chmod($keyDir, 0770);
    }

    $cmd = "sudo -u apache /usr/sbin/opendkim-genkey -D " . escapeshellarg($keyDir) .
           " -d " . escapeshellarg($domain) .
           " -s default";
    shell_exec($cmd);

    $private = "$keyDir/default.private";
    $txt     = "$keyDir/default.txt";

    if (!file_exists($private) || !file_exists($txt)) {
        log_msg("DKIM generation failed for $domain");
        return ['private' => '', 'public' => ''];
    }

    $privateKey = file_get_contents($private);
    $publicRaw  = file_get_contents($txt);

    preg_match('/p=([^"]+)/', $publicRaw, $m);
    $publicKey = $m[1] ?? '';

    log_msg("DKIM: keyDir = $keyDir");
    log_msg("DKIM: dir exists? " . (is_dir($keyDir) ? 'yes' : 'no'));
    log_msg("DKIM: running opendkim-genkey");
    log_msg("DKIM: private exists? " . (file_exists($private) ? 'yes' : 'no'));
    log_msg("DKIM: txt exists? " . (file_exists($txt) ? 'yes' : 'no'));

    log_msg("DKIM keys generated for $domain");

    return [
        'private' => $privateKey,
        'public'  => $publicKey
    ];
}

$dkim = generate_dkim_keys($domain, $opendkimKeyRoot);

// Safe DKIM splitting
$pub = $dkim['public'];
$chunks = [];
while (strlen($pub) > 0) {
    $chunks[] = substr($pub, 0, 200);
    $pub = substr($pub, 200);
}
$dkim_p1 = $chunks[0] ?? '';
$dkim_p2 = $chunks[1] ?? '';

// =========================
// GOLDEN ZONE TEMPLATE
// =========================
$template = <<<ZONE
\$TTL 3600
@   IN SOA ns1.{DOMAIN}. admin.{DOMAIN}. (
        {SERIAL}
        3600
        1800
        604800
        86400 )

ns1     IN A {IPV4}
ns2     IN A {IPV4}

@       IN NS ns1.{DOMAIN}.
@       IN NS ns2.{DOMAIN}.

@       IN A {IPV4}
www     IN CNAME {DOMAIN}.

mail    IN A {IPV4}
@       IN MX 10 mail.{DOMAIN}.

@       IN TXT "v=spf1 mx a ip4:{IPV4} include:_spf.systapp.com -all"

default._domainkey IN TXT (
    "{DKIM_P1}"
    "{DKIM_P2}"
)

_dmarc IN TXT "v=DMARC1; p=reject; rua=mailto:dmarc@{DOMAIN}"

@ IN CAA 0 issue "letsencrypt.org"

autodiscover IN SRV 0 0 443 server.systapp.com.
autoconfig   IN CNAME server.systapp.com.

ZONE;

$template = str_replace('{DOMAIN}', $domain, $template);
$template = str_replace('{IPV4}',   $ipv4,   $template);
$template = str_replace('{SERIAL}', $serial, $template);
$template = str_replace('{DKIM_P1}', $dkim_p1, $template);
$template = str_replace('{DKIM_P2}', $dkim_p2, $template);

$zonePath = "$namedZoneDir/{$domain}.hosts";
file_put_contents($zonePath, $template);
log_msg("Zonefile written: $zonePath");

// =========================
// DNSSEC KEY GENERATION + SIGNING
// =========================
function dnssec_sign_zone(string $domain, string $zonePath, string $keyRoot, string $namedZoneDir): ?string {
    $keyDir = "$keyRoot/$domain";

    if (!is_dir($keyDir)) {
        mkdir($keyDir, 0750, true);
    }

    $cmdKey = "cd " . escapeshellarg($keyDir) .
              " && dnssec-keygen -a ECDSAP256SHA256 -n ZONE " . escapeshellarg($domain);
    shell_exec($cmdKey);

    $cmdSign = "cd " . escapeshellarg($namedZoneDir) .
               " && dnssec-signzone -o " . escapeshellarg($domain) .
               " " . escapeshellarg($zonePath);
    shell_exec($cmdSign);

    $signedPath = $zonePath . ".signed";
    if (!file_exists($signedPath)) {
        log_msg("DNSSEC signing failed for $domain");
        return null;
    }

    log_msg("DNSSEC signed zone created: $signedPath");
    return $signedPath;
}

$signedZonePath   = dnssec_sign_zone($domain, $zonePath, $dnssecKeyRoot, $namedZoneDir);
$zoneFileForNamed = $signedZonePath ?? $zonePath;

// =========================
// NAMED CONF AUTO-INCLUDE
// =========================
$zoneStanza = <<<CONF

zone "$domain" IN {
    type master;
    file "$zoneFileForNamed";
};

CONF;

file_put_contents($namedConf, $zoneStanza, FILE_APPEND);
log_msg("Named.conf updated for $domain");

// =========================
// OPEN DKIM CONFIG
// =========================
file_put_contents(
    $opendkimKeyTable,
    "default._domainkey.$domain $domain:default:/etc/opendkim/keys/$domain/default.private\n",
    FILE_APPEND
);

file_put_contents(
    $opendkimSignTable,
    "*@$domain default._domainkey.$domain\n",
    FILE_APPEND
);

file_put_contents(
    $opendkimTrusted,
    "$domain\n",
    FILE_APPEND
);

log_msg("OpenDKIM tables updated for $domain");

// =========================
// DMARC REPORTING MAILBOX (alias to root)
// =========================
file_put_contents($aliasesFile, "dmarc@$domain: root\n", FILE_APPEND);
shell_exec("newaliases");
log_msg("DMARC alias created: dmarc@$domain -> root");

// =========================
// CREATE SYSTAPP MODE DIRECTORY STRUCTURE
// =========================
$homeRoot = "/home/$domain";
$dirs = ['etc', 'logs', 'mail', 'public_html', 'tmp'];

if (!is_dir($homeRoot)) {
    if (!mkdir($homeRoot, 0755, true)) {
        log_msg("ERROR: Failed to create homeRoot $homeRoot");
    } else {
        log_msg("homeRoot created: $homeRoot");
    }
} else {
    log_msg("homeRoot already exists: $homeRoot");
}

foreach ($dirs as $d) {
    $path = "$homeRoot/$d";
    if (!is_dir($path)) {
        if (!mkdir($path, 0755, true)) {
            log_msg("ERROR: Failed to create subdir $path");
        } else {
            log_msg("Subdir created: $path");
        }
    } else {
        log_msg("Subdir already exists: $path");
    }
}

if (!is_dir($homeRoot)) {
    log_msg("ERROR: Post-check: homeRoot still missing: $homeRoot");
} else {
    log_msg("Post-check: homeRoot exists: $homeRoot");
}


// =========================
// UNDER-CONSTRUCTION INDEX.PHP
// =========================
$indexFile = "$homeRoot/public_html/index.php";

$indexContent = <<<HTML
<!DOCTYPE html>
<html>
<head>
<title>$domain - Under Construction</title>
<style>
body { background:#0f172a; color:#e5e7eb; font-family:sans-serif; text-align:center; padding-top:10%; }
.box { background:#1e293b; padding:40px; border-radius:12px; display:inline-block; }
</style>
</head>
<body>
<div class="box">
<h1>$domain</h1>
<p>This site is currently under construction.</p>
<p>SYSTAPP MODE infrastructure is provisioning DNS, mail, and security.</p>
</div>
</body>
</html>
HTML;

$result = file_put_contents($indexFile, $indexContent);
if ($result === false) {
    log_msg("ERROR: Failed to write index.php to $indexFile");
} else {
    log_msg("Under-construction index.php written to $indexFile (bytes: $result)");
}

if (!file_exists($indexFile)) {
    log_msg("ERROR: Post-check: index.php missing at $indexFile");
} else {
    log_msg("Post-check: index.php exists at $indexFile");
}

// =========================
// OWNERSHIP + PERMISSIONS
// =========================
shell_exec("chown -R " . escapeshellarg($ownerUser) . ":" . escapeshellarg($ownerGroup) . " " . escapeshellarg($homeRoot));
shell_exec("chmod -R 755 " . escapeshellarg($homeRoot));
shell_exec("restorecon -RF " . escapeshellarg($homeRoot));
log_msg("Ownership set to $ownerUser:$ownerGroup for $homeRoot");

// =========================
// RELOAD SERVICES
// =========================
shell_exec("systemctl reload named");
shell_exec("systemctl reload opendkim");
log_msg("named and opendkim reloaded for $domain");

// =========================
// DONE
// =========================
log_msg("Provisioning completed for $domain");

echo json_encode([
    'ok' => true,
    'message' => "Domain $domain fully provisioned with DNS, DKIM, DMARC, SPF, DNSSEC, SYSTAPP MODE directories, and web root."
]);

?>

