<?php
// chatbot/rag/gcs_helper.php

class GCSHelper {
    private $bucketName;
    private $serviceAccountPath;
    private $accessToken = null;

    public function __construct() {
        // Load Bucket Name
        $configFile = dirname(__DIR__, 2) . '/apikey/gcs_config.txt';
        if (file_exists($configFile)) {
            $config = parse_ini_file($configFile);
            $this->bucketName = $config['bucket_name'] ?? null;
        }

        // Load Service Account Path
        $this->serviceAccountPath = dirname(__DIR__, 2) . '/apikey/google_service_account.json';
    }

    public function getBucketName() {
        return $this->bucketName;
    }

    private function getAccessToken() {
        if ($this->accessToken) return $this->accessToken;

        if (!file_exists($this->serviceAccountPath)) {
            throw new Exception("Service account file not found: " . $this->serviceAccountPath);
        }

        $serviceAccount = json_decode(file_get_contents($this->serviceAccountPath), true);
        if (!$serviceAccount) {
            throw new Exception("Invalid service account JSON");
        }

        $now = time();
        $jwtHeader = base64_encode(json_encode(['alg' => 'RS256', 'typ' => 'JWT']));
        $jwtClaim = base64_encode(json_encode([
            'iss' => $serviceAccount['client_email'],
            'scope' => 'https://www.googleapis.com/auth/devstorage.full_control',
            'aud' => 'https://oauth2.googleapis.com/token',
            'exp' => $now + 3600,
            'iat' => $now
        ]));

        $privateKey = openssl_pkey_get_private($serviceAccount['private_key']);
        if (!$privateKey) throw new Exception("Failed to load private key");

        openssl_sign($jwtHeader . '.' . $jwtClaim, $signature, $privateKey, OPENSSL_ALGO_SHA256);
        openssl_free_key($privateKey);

        $jwt = $jwtHeader . '.' . $jwtClaim . '.' . base64_encode($signature);

        $ch = curl_init('https://oauth2.googleapis.com/token');
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
            'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
            'assertion' => $jwt
        ]));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($httpCode !== 200) {
            throw new Exception("Failed to get OAuth token: " . $response);
        }

        $data = json_decode($response, true);
        $this->accessToken = $data['access_token'];
        return $this->accessToken;
    }

    public function upload($filePath, $objectName) {
        $token = $this->getAccessToken();
        
        $fileContent = file_get_contents($filePath);
        $mimeType = 'application/json';
        
        $url = 'https://storage.googleapis.com/upload/storage/v1/b/' . 
               urlencode($this->bucketName) . '/o?uploadType=media&name=' . 
               urlencode($objectName);

        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Authorization: Bearer ' . $token,
            'Content-Type: ' . $mimeType,
            'Content-Length: ' . strlen($fileContent)
        ]);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $fileContent);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($httpCode == 200) {
            return true;
        } else {
            throw new Exception("GCS Upload Failed ($httpCode): " . $response);
        }
    }

    public function download($objectName, $savePath) {
        $token = $this->getAccessToken();
        
        $url = 'https://storage.googleapis.com/storage/v1/b/' . 
               urlencode($this->bucketName) . '/o/' . 
               urlencode($objectName) . '?alt=media';

        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Authorization: Bearer ' . $token
        ]);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        
        $content = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($httpCode == 200) {
            file_put_contents($savePath, $content);
            return true;
        } else {
            throw new Exception("GCS Download Failed ($httpCode)");
        }
    }
}
?>
