<?php
require_once __DIR__ . '/google-api-php-client/vendor/autoload.php';
require_once "googleRTBCreative.php";

class googleRTBCreativeLib extends googleRTBCreative
{
    const KEY = __DIR__."/rtb_key.json";
    const BUYER_NAME = "buyers/195568039";
    const SCOPE = "https://www.googleapis.com/auth/realtime-bidding";
    const CreativeApplicationName = "Authorized Buyers Real-time Bidding API";
    const URL = "https://localpages.com/result?term=%s";
    const SUCCESS = "success";
    const FAILED = "failed";

    private $_requiredCreativeParams = array("creative_id"=>"string","keywords"=>"array","html_width"=>"int","html_height"=>"int","html_snippet"=>"string");

    public function __construct() {
        //Constructor Code
        if(!file_exists(self::KEY)){
            die("Authenticate File Needed");
        }
    }
    /**
     * Init oogle Client
     */
    private function _initGoogleClient() {
        $this->client = new Google_Client();
        $this->client->setApplicationName(self::CreativeApplicationName);
        $this->client->setAuthConfig(self::KEY);
        $this->client->addScope(self::SCOPE);
        if ($this->client->isAccessTokenExpired()) {
            $this->client->refreshTokenWithAssertion();
        }
    }
    /**
     * Create Creative at Google Adx For Approval
     * @param array $params
     * $params = array(
     * "creative_id"=>"Creative Unique Name" // Required
     * "keywords"=>"keyword Array used In html" // Required
     * "html_width"=>"Width for Ad" // Required
     * "html_height"=>"height for Ad" // Required
     * "html_snippet"=>"html code that will shown" // Required
     * declared_click_urls=click urls for keywords //optional
     * "account_id"=>"Google Account ID" // Optional
     * "advertiser_name"=>"Advertiser name " // Optional
     * "declared_attributes"=>"" // Optional
     * "declared_restricted_categories"=>"" // Optional
     * "declared_vendor_ids"=>"" // Optional
     * )
     * 
     */
    public function createCreative($params) {
        if($this->_validateCreateCreativeInput($params)){
            $values = $this->_formInput($params,"createCreativeValidData");
            $this->_initGoogleClient();
            $this->service = new Google_Service_RealTimeBidding($this->client); 
            
            $html = new Google_Service_RealTimeBidding_HtmlContent();
            $html->snippet = $values['html_snippet'];
            $html->height = $values['html_height'];
            $html->width = $values['html_width'];

            $newCreative = new Google_Service_RealTimeBidding_Creative();
            $newCreative->advertiserName = $values['advertiser_name'];
            $newCreative->creativeId = $values['creative_id'];
            $newCreative->declaredAttributes = $values['declared_attributes'];
            $newCreative->declaredClickThroughUrls = $values['declared_click_urls'];
            $newCreative->declaredRestrictedCategories = $values['declared_restricted_categories'];
            $newCreative->declaredVendorIds = $values['declared_vendor_ids'];
            $newCreative->setHtml($html);

            try {
                // Call the buyers.creatives.create method to submit a creative for the given buyer.
                $result = $this->service->buyers_creatives->create(self::BUYER_NAME,$newCreative);
                return array("status"=> self::SUCCESS,"response"=>$result,"error"=>null);
            } catch( Exception $e) {
                $error= [];
                $error["msg"] = $e->getMessage();
                return array("status"=> self::FAILED,"response"=>null,"error"=>$error);
            }
        }else{
            return array("status"=> self::FAILED,"response"=>null,"error"=>array("msg"=>"Invalid Input"));
        }
    }
    /**
     * Get Creative Status
     * @param string $creativeId Creative Name
     */
    public function getCreativestatus($creativeId) {
        if(!empty($creativeId)){
            $this->_initGoogleClient();
            $this->service = new Google_Service_RealTimeBidding($this->client); 
            $values = $this->_formInput(array("creative_id"=>$creativeId),"getCreativeValidData");
            $name = "buyers/{$values['account_id']}/creatives/{$values['creative_id']}";
            try {
                $creative = $this->service->buyers_creatives->get($name);
                $response = [];
                $response['status'] = $creative->creativeServingDecision->networkPolicyCompliance->status;
                $response['raw_response'] = $creative;
                return array("status"=> self::SUCCESS,"response"=>$response,"error"=>$creative);
            } catch (Google_Service_Exception $ex) {
                $error = [];
                if ($ex->getCode() === 404 || $ex->getCode() === 403) {
                    $error['msg'] = "Creative Not Found";
                } else {
                    $error['msg'] = $ex->getMessage();
                }
                return array("status"=> self::FAILED,"response"=>null,"error"=>$error);
            }
        }else{
           return array("status"=> self::FAILED,"response"=>null,"error"=>array("msg"=>"Invalid Input")); 
        }
    }
    /**
     * Update creative on google
     * @param type $params
     */
    public function UpdateCreative($params) {
        
        if(!empty($params) && $this->_validateCreateCreativeInput($params)){
            $this->_initGoogleClient();
            $this->service = new Google_Service_RealTimeBidding($this->client); 
            $values = $this->_formInput($params,"updateCreativeValidData");
            $name = "buyers/{$values['account_id']}/creatives/{$values['creative_id']}";

            
            //Updated params
            $html = new Google_Service_RealTimeBidding_HtmlContent();
            $html->snippet = $values['html_snippet'];

            $patchedCreative = new Google_Service_RealTimeBidding_Creative();
            $patchedCreative->declaredClickThroughUrls = $values['declared_click_urls'];
            $patchedCreative->setHtml($html);
            
            $queryParams = [
                'updateMask' => 'html,declaredClickThroughUrls'
            ];
            
            try {
                // Call the buyers.creatives.patch method to update a creative for the given buyer.
                $result = $this->service->buyers_creatives->patch($name, $patchedCreative, $queryParams);
                return array("status"=> self::SUCCESS,"response"=>$result,"error"=>null);
            } catch( Exception $e) {
                $error= [];
                $error["msg"] = $e->getMessage();
                return array("status"=> self::FAILED,"response"=>null,"error"=>$error);
            }
        }else{
            return array("status"=> self::FAILED,"response"=>null,"error"=>array("msg"=>"Invalid Input")); 
        }
    }
    
    
    /**
     * Form input Needed By Google
     * @param type $params
     * @return type
     */
    private function _formInput($params,$fun) {
        $input = [];
        if($fun == "createCreativeValidData"){
            $elmentNeedToForm = array("declared_click_urls");
            foreach ($elmentNeedToForm as $value) {
                if(empty($params[$value]))
                    $params[$value] = $this->{$value}($params);
            }   
        }
        $inputArray = $this->{$fun}();
        foreach ($inputArray as $parameter) {
            if (isset($params[$parameter['name']]) && !empty($params[$parameter['name']])) {
                if (isset($parameter['is_array']) and $parameter['is_array']) {
                    $input[$parameter['name']] = explode(',', $params[$parameter['name']]);
                } else {
                    $input[$parameter['name']] = $params[$parameter['name']];
                }
            } elseif (!empty($parameter['default'])) {
                $input[$parameter['name']] = $parameter['default'];
            } else {
                $input[$parameter['name']] = null;
            }
        }
        return $input;
    }
    /**
     * Validate Input
     * @param type $params
     * @return boolean
     */
    private function _validateCreateCreativeInput($params) {
        $valid = true;
        $flag = 0;
        foreach ($this->_requiredCreativeParams as $key=>$type) {
            if(!isset($params[$key]) || empty($params[$key])){
                $valid = false;
                break;
            }
            switch ($type){
                case "array":
                    $flag = is_array($params[$key]) ? 0 : 1;
                    break;
                case "int":
                    $flag = is_integer($params[$key]) ? 0 : 1;
                    break;
                default:
                    break;
            }
            if($flag == 1){
                $valid = false;
                break;
            }
        }
        return $valid;
    }
    /**
     * Create declared_click_urls for googles
     * @param type $params
     * @return type
     */
    private function declared_click_urls($params) {
        $urls = [];
        foreach($params['keywords'] as $keyword){
            $urls[] = sprintf(self::URL, urlencode($keyword));
        }
        return $urls;
    }

    /**
     * This method is used to List pretargetingconfigs
     * @param type $params
     * @return type array()
     */
    public function getPretargetingList($params = []) {
        $this->_initGoogleClient();
        $this->service = new Google_Service_RealTimeBidding($this->client);
        $values = $this->_formInput($params, "getPretargtingListValidData");
        $parent_name = "bidders/{$values['account_id']}";
        $query_params = ['pageSize' => $values['page_size']];
        try {
            $pretargetings = $this->service->bidders_pretargetingConfigs->listBiddersPretargetingConfigs($parent_name, $query_params);
            $response_json = json_encode($pretargetings, true);
            return array("status" => self::SUCCESS, "response" => $response_json, "error" => $response_json);
        } catch (Google_Service_Exception $ex) {
            $error = [];
            if ($ex->getCode() === 404 || $ex->getCode() === 403) {
                $error['msg'] = "Pretargetings Not Found";
            } else {
                $error['msg'] = $ex->getMessage();
            }
            return array("status" => self::FAILED, "response" => null, "error" => $error);
        }
    }
    
    /**
     * Get All Creative list
     */
    public function getAllCreatives() {
        $this->_initGoogleClient();
        $this->service = new Google_Service_RealTimeBidding($this->client); 
        $values = $this->_formInput(array(),"getAllCreativeList");
        $name = "buyers/{$values['account_id']}";
        $queryParams = [
            'filter' => $values['filter'],
            'pageSize' => 1000,
            'view' => $values['view']
        ];
        try {
            $result = $this->service->buyers_creatives->listBuyersCreatives($name, $queryParams);
            $allCreatives = $result->getCreatives();
            $result = [];
            foreach ($allCreatives as $key => $creative) {
                $result[] = $creative->getCreativeId();
            }
            return array("status"=> self::SUCCESS,"response"=>$result,"error"=>null);
        } catch (Google_Service_Exception $ex) {
            $error = [];
            if ($ex->getCode() === 404 || $ex->getCode() === 403) {
                $error['msg'] = "Creative Not Found";
            } else {
                $error['msg'] = $ex->getMessage();
            }
            return array("status"=> self::FAILED,"response"=>null,"error"=>$error);
        }
    }
}
