<?php

namespace Api\PhpUtils\Protobuf\WebsiteLog;

use Api\PhpUtils\Http\Request;
use Gateway\Data\Rawlog\AppMeta;
use  Gateway\Data\Rawlog\UID;
use Gateway\Data\Rawlog\WebsiteLog;
use http\Exception;
use Api\PhpUtils\Log;


require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Gateway/Data/Rawlog/WebsiteLog.php';
//require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Yidian/Data/Rawlog/UID_Type.php';
require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Gateway/Data/Rawlog/UID.php';
require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Gateway/Data/Rawlog/UID/Type.php';
require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Gateway/Data/Rawlog/AppMeta.php';
require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Gateway/Data/Rawlog/Platform.php';
require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'GPBMetadata/Websitelog.php';



class WebLog
{
    private const BP_WEBSITE_PB_LOG_URL = 'http://online-feedback-receiver.ha.in.yidian.com:9088/OnlineFeedbackReceiver/ProtobufStreamHandler?topic=rawlog_bp_api_bp_gateway_prod';
    /**
     * 日志格式转pb格式
     *
     * @param array $log
     * @return string
     */
    public function log2pb(array $log) : string
    {
        try
        {
            //message对象
            $uid = new UID();
            $app_meta = new AppMeta();
            $website_log = new WebsiteLog();

            $action = $this->formatAction($_SERVER['action']);

            $platform_list = array(
                "IOS"     => 0,
                "Android" => 1,
                "Web"     => 2,
                "Unknown" => -1
            ); //平台列表

            //app_meta属性赋值
            //App相关配置
            $app_meta->setAppId($log['request']['appid'] ?? ''); //appid
            $app_meta->setBundleVersion($log['request']['clientInfo']['userInfo']['appVersion'] ?? $log['request']['log']['bundle_version'] ?? '');
            $app_meta->setDistributionChannel($log['request']['distribution'] ?? '');
            $app_meta->setImei($log['request']['clientInfo']['userInfo']['imei'] ?? $log['request']['imei'] ?? '');
            $app_meta->setMacId($log['request']['clientInfo']['userInfo']['mac'] ?? $log['request']['mac'] ?? '');
            $app_meta->setAndroidId($log['request']['clientInfo']['userInfo']['androidId'] ?? $log['request']['androidId'] ?? '');

            //设备相关的元数据
            $app_meta->setDeviceName($log['request']['clientInfo']['deviceInfo']['deviceName'] ?? $log['request']['deviceName'] ?? $log['request']['clientInfo']['deviceInfo']['model'] ?? '');
            $app_meta->setBrand($log['request']['clientInfo']['deviceInfo']['brand'] ?? $log['request']['deviceBrand'] ?? '');
            $app_meta->setScreenDensity($log['request']['clientInfo']['deviceInfo']['screenDensity'] ?? '');
            if (isset($log['request']['clientInfo']['deviceInfo']['screenWidth']) && is_numeric($log['request']['clientInfo']['deviceInfo']['screenWidth']))
            {
                $app_meta->setScreenWidth((int)$log['request']['clientInfo']['deviceInfo']['screenWidth']);
            }
            if (isset($log['request']['clientInfo']['deviceInfo']['screenHeight']) && is_numeric($log['request']['clientInfo']['deviceInfo']['screenHeight']))
            {
                $app_meta->setScreentHeight((int)$log['request']['clientInfo']['deviceInfo']['screenHeight']);
            }
            //操作系统相关配置
            if (isset($log['request']['platform']) && is_numeric($log['request']['platform']) && in_array($log['request']['platform'], $platform_list))
            {
                $app_meta->setPlatform((int)$log['request']['platform']);
            }
            else
            {
                $app_meta->setPlatform(-1);
            }
            $app_meta->setOperatingSystem($log['request']['clientInfo']['deviceInfo']['androidVersion'] ?? $log['request']['clientInfo']['deviceInfo']['iosVersion'] ?? '');
            $app_meta->setLanguage($log['request']['clientInfo']['userInfo']['language'] ?? '');
            $app_meta->setCountry($log['request']['clientInfo']['userInfo']['country'] ?? '');
            //iOS相关的信息
            $app_meta->setIosAdvertisingIdentifier($log['request']['clientInfo']['userInfo']['ifa'] ?? $log['request']['clientInfo']['app_info']['ifa'] ?? '');
            $app_meta->setIosIdentifierForVendor($log['request']['clientInfo']['app_info']['idfv'] ?? '');

            //uid属性赋值
            if (isset($log['request']['userid']) && is_numeric($log['request']['userid']))
            {
                $uid->setUserId((int)$log['request']['userid']); //userid
            }
            $uid->setDeviceId($log['request']['deviceid'] ?? $log['request']['clientInfo']['app_info']['device_id'] ?? '');
            $uid->setUserName($log['request']['username'] ?? '');
            $uid->setUserType($log['request']['usertype'] ?? '');
            if (isset($log['request']['log']['bucket_id']) && is_numeric($log['request']['bucket_id']))
            {
                $uid->setBucketId($log['request']['log']['bucket_id']);
            }
            $uid->setIsSuperAccount($log['request']['is_super_account'] ?? false);
            $uid->setWid($log['request']['wid'] ?? '');

            //website_log属性赋值
            $website_log->setRequestTimeMs(isset($log['request_time']) ? floor($log['request_time'] * 1000) : 0);
            $website_log->setResponseTimeMs(isset($log['response_time']) ? floor($log['response_time'] * 1000) : 0);
            $website_log->setAction($action);
            $website_log->setRecvTimeMs(isset($log['recv_time']) ? floor($log['recv_time'] * 1000) : 0);
            $website_log->setRemoteHost($log['request']['clientInfo']['userInfo']['ip'] ?? '');
            $website_log->setChecksum($log['request']['checksum'] ?? '');
            //request内容
            $website_log->setAppMeta($app_meta);
            $website_log->setApiVersion($log['request']['version'] ?? '');
            $website_log->setUid($uid);
            $website_log->setReqid($log['request']['requestId'] ?? $log['request']['reqid'] ?? '');
            //response内容
            $website_log->setStatus($log['response']['status'] ?? 'success');
            $website_log->setCode($log['response']['code'] ?? 0);
            $website_log->setReason($log['response']['reason'] ?? '');
            return $website_log->serializeToString(); //序列化
        } catch (Exception $e)
        {
            return '';
        }
    }

    /**
     * 格式化action: (1)将 // 替换成 /; (2)去掉开头的/; (3)/ 和 - 替换为 _; (4)转换为小写
     *
     * @param $action
     * @return mixed
     */
    private function formatAction($action)
    {
        $tmp1 = str_replace('//', '/', $action);
        $tmp2 = strtolower(substr($tmp1, 1, strlen($tmp1) - 1));
        return str_replace(array('/', '-'), '_', $tmp2);
    }

    /**
     * 发送pb 日志
     * @param $result
     * @param int $percentage
     * @param bool $send_request
     * @param string $action
     */
    public function sendPbLog($result,$percentage = 100, $send_request = true, $action = '')
    {
        if ($percentage >= 100 || $_SERVER['REQUEST_TIME'] % 100 < $percentage)
        {
            $log = array(
                'request_time'      => $_SERVER['REQUEST_TIME_FLOAT'],
                'response_time'     => microtime(true)
            );

            $log['action'] = $action ?? explode('?', $_SERVER['REQUEST_URI'])[0];

            if ($send_request === true)
            {
                $log['request'] = array_merge( $_GET, $_POST );
            } else if ($send_request !== false) {
                $log['request'] = $send_request;
            }

            $log['response']['status'] = $result['status']??'';
            $log['response']['code'] = $result['code']??'';
            $log['response']['reason'] = $result['reason']??'';

            if( !empty($GLOBALS['related_url']) )
            {
                $log['response']['related_url'] = $GLOBALS['related_url'];
            }

            if (extension_loaded('protobuf'))
            {
                $data = $this->log2pb($log);
                if (!empty($data))
                {
                    $bp_website_pb_log_url = self::BP_WEBSITE_PB_LOG_URL;
                    $res = (new Request())->post($bp_website_pb_log_url, $data, 50, ['Content-Type: binary/octet-stream'], [], 1);
                }
            }

        }
    }
}