<?php

// Include Alibaba Cloud SDK
require_once __DIR__ . '/vendor/autoload.php';

use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
use AlibabaCloud\Sts\Sts;

// Disable error display
ini_set('display_errors', '0');

$bucket = 'examplebucket'; // Replace with your Bucket name
$region_id = 'cn-hangzhou'; // Replace with your Bucket region
$host = 'http://examplebucket.oss-cn-hangzhou.aliyuncs.com'; // Replace with your Bucket domain
$expire_time = 3600; // Expiration time in seconds
$upload_dir = 'user-dir'; // Prefix for uploaded files
// $callbackUrl is the URL of the upload callback server. Please configure the IP and port as your real URL information.
$callbackUrl = 'http://oss-demo.aliyuncs.com:23450/callback';

// Calculate HMAC-SHA256
function hmacsha256($key, $data) {
    return hash_hmac('sha256', $data, $key, true);
}

// Handle GET request for POST signature
if ($_SERVER['REQUEST_METHOD'] === 'GET' && $_SERVER['REQUEST_URI'] === '/get_post_signature_for_oss_upload') {

    AlibabaCloud::accessKeyClient(getenv('OSS_ACCESS_KEY_ID'), getenv('OSS_ACCESS_KEY_SECRET'))
        ->regionId('cn-hangzhou')
        ->asDefaultClient();
    // Create STS request.
    $request = Sts::v20150401()->assumeRole();
    // Send STS request and get result.
    // Set <YOUR_ROLE_SESSION_NAME> to a custom session name, e.g., oss-role-session.
    // Replace <YOUR_ROLE_ARN> with the ARN of the RAM role with permission to upload files to the specified OSS Bucket.
    $result = $request
        ->withRoleSessionName('oss-role-session')
        ->withDurationSeconds(3600)
        ->withRoleArn(getenv('OSS_STS_ROLE_ARN')) // Replace with your RAM role ARN
        ->request();
    // Get credential information from the STS request result.
    $tokenData = $result->get('Credentials');
    // Construct the JSON data to be returned.
    $tempAccessKeyId = $tokenData['AccessKeyId'];
    $tempAccessKeySecret = $tokenData['AccessKeySecret'];
    $securityToken = $tokenData['SecurityToken'];

    $now = time();
    $dtObj = gmdate('Ymd\THis\Z', $now);
    $dtObj1 = gmdate('Ymd', $now);
    $dtObjPlus3h = gmdate('Y-m-d\TH:i:s.u\Z', strtotime('+3 hours', $now));

    // Construct Policy
    $policy = [
        "expiration" => $dtObjPlus3h,
        "conditions" => [
            ["x-oss-signature-version" => "OSS4-HMAC-SHA256"],
            ["x-oss-credential" => "{$tempAccessKeyId}/{$dtObj1}/cn-hangzhou/oss/aliyun_v4_request"],
            ["x-oss-security-token" => $securityToken],
            ["x-oss-date" => $dtObj],
        ]
    ];

    $policyStr = json_encode($policy);

    // Construct string to sign
    $stringToSign = base64_encode($policyStr);

    // Calculate SigningKey
    $dateKey = hmacsha256(('aliyun_v4' . $tempAccessKeySecret), $dtObj1);
    $dateRegionKey = hmacsha256($dateKey, 'cn-hangzhou');
    $dateRegionServiceKey = hmacsha256($dateRegionKey, 'oss');
    $signingKey = hmacsha256($dateRegionServiceKey, 'aliyun_v4_request');

    // Calculate Signature
    $result = hmacsha256($signingKey, $stringToSign);
    $signature = bin2hex($result);
    
    $callback_param = array(
    'callbackUrl' => $callbackUrl,
    'callbackBody' => 'filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}',
    'callbackBodyType' => "application/x-www-form-urlencoded"
    );
    $callback_string = json_encode($callback_param);

    $base64_callback_body = base64_encode($callback_string);

    // Return signature data
    $responseData = [
        'policy' => $stringToSign,
        'x_oss_signature_version' => "OSS4-HMAC-SHA256",
        'x_oss_credential' => "{$tempAccessKeyId}/{$dtObj1}/cn-hangzhou/oss/aliyun_v4_request",
        'x_oss_date' => $dtObj,
        'signature' => $signature,
        'host' => $host,
        'dir' => $upload_dir,
        'security_token' => $securityToken,
        'callback' => $base64_callback_body,
    ];

    header('Content-Type: application/json');
    echo json_encode($responseData);
    exit;
}

// Home route
if ($_SERVER['REQUEST_METHOD'] === 'GET' && $_SERVER['REQUEST_URI'] === '/') {
    echo file_get_contents(__DIR__ . '/public/index.html');
    exit;
}

// Other routes
http_response_code(404);
echo json_encode(['message' => 'Not Found']);
exit;
?>