<?php

# Imports the Google Cloud client libraries
use Google\ApiCore\ApiException;
use Google\Cloud\Kms\V1\CryptoKey;
use Google\Cloud\Kms\V1\CryptoKey\CryptoKeyPurpose;
use Google\Cloud\Kms\V1\KeyManagementServiceClient;
use Google\Cloud\Kms\V1\KeyRing;

class GoogleKMS {

    private $client;
    private $projectId;
    private $authFile;

    private $keyRing = NULL;
    private $keyRingId = NULL;
    private $keyRingName = NULL;
    private $keyName = NULL;
    private $cryptoKey = NULL;
    private $location = 'global';

    public function __construct($projectId, $authFile, $keyRingId=NULL, $keyId=NULL) {
        // Your Google Cloud Platform project ID
        $this->projectId = $projectId; // 'float-app-224118';
        // The file path to credentials JSON
        //error_log($authFile);
        putenv("GOOGLE_APPLICATION_CREDENTIALS=${authFile}");
        apache_setenv("GOOGLE_APPLICATION_CREDENTIALS",$authFile,true);
        $this->authFile = $authFile; // './float-app-224118-52ef1783d2c5.json';
        // Instantiates a client
        $this->client = new KeyManagementServiceClient([
            'projectId' => $projectId,
            'keyFile' => json_decode(file_get_contents($authFile), true)
        ]);
        if ($keyRingId!=NULL) {
            $this->createKeyring($keyRingId);
            if ($keyId!=NULL) {
                $this->createCryptokey($keyId);
            }
        }
    }

    public function createKeyring($keyRingId) {
        try {
            $locationName = $this->client::locationName(
                $this->projectId, 
                $this->location
            );
            $keyRingName = $this->client::keyRingName(
                $this->projectId, 
                $this->location, 
                $keyRingId
            );
            $this->keyRing = $this->client->getKeyRing($keyRingName);
            $this->keyRingId = $keyRingId;
            $this->keyRingName = $keyRingName;
        } catch (ApiException $e) {
            if ($e->getStatus() === 'NOT_FOUND') {
                $this->keyRing = new KeyRing();
                $this->keyRing->setName($keyRingName);
                $this->client->createKeyRing(
                    $locationName, 
                    $keyRingId, 
                    $this->keyRing);
                $this->keyRingId = $keyRingId;
                $this->keyRingName = $keyRingName;
            }
        }
        return $this->keyRing;
    }

    public function createCryptokey($keyId) {
        try {
            $keyName = $this->client::cryptoKeyName(
                $this->projectId, 
                $this->location, 
                $this->keyRingId, 
                $keyId);
            $this->cryptoKey = $this->client->getCryptoKey($keyName);
            $this->keyName = $keyName;
        } catch (ApiException $e) {
            if ($e->getStatus() === 'NOT_FOUND') {
                $this->cryptoKey = new CryptoKey();
                $this->cryptoKey->setPurpose(CryptoKeyPurpose::ENCRYPT_DECRYPT);
                $this->cryptoKey = $this->client->createCryptoKey(
                    $this->keyRingName, 
                    $keyId,
                    $this->cryptoKey);
                $this->keyName = $keyName;
            }
        }
        return $this->cryptoKey;
    }

    public function encrypt($secret) {
        $response = $this->client->encrypt($this->keyName, $secret);
        $cipherText = $response->getCiphertext();
        return $cipherText;
    }

    public function decrypt($cipherText) {
        $response = $this->client->decrypt($this->keyName, $cipherText);
        $plainText = $response->getPlaintext();
        return $plainText;
    }
}

    