<?php
# Usage :
#   php test_ncloud.php name email date
#   php test_ncloud.php 삼화초 jisangs@daum.net "2019년 4월 25일"

class MailSender {

    private $mailSetting = null;

    private $senderName = "";
    private $senderEmail = "";

    private $isPost = false;
    private $postParam = null;


    private function showParameters($params) {
        if($params == null || count($params) == 0)
            return;

        echo "=====\n";
        // echo count($params)."\n";
        // echo $params."\n";
        foreach($params as $pKey => $pValue) {
            echo "    ".$pKey." : ".$pValue."\n";
        }
        echo "=====\n";
    }

    private function showRecipients($params) {
        if($params == null || count($params) == 0)
            return;

        echo "=====\n";
        echo count($params)."\n";
        echo $params."\n";
        foreach($params as $pKey => $pValue) {
            echo "    ".$pKey." : ".$pValue."\n";
            foreach($params[$pKey] as $aKey => $aValue) {
                echo "        ".$aKey." : ".$aValue."\n";
            }
        }
        echo "=====\n";
    }

    public function showSettings() {
        echo "\n";
        echo "mailSetting : ".$this->mailSetting->hostNameUrl."\n\r";
        echo "senderName : ".$this->senderName."\n\r";
        echo "senderEmail : ".$this->senderEmail."\n\r";

        if($this->postParam == null) {
            echo "no postParam\n";
            return;
        }

        echo "\n*************************\n";
        foreach($this->postParam as $key => $value) {
            echo $key." : ".$value."\n";
            if($key == "parameters") {
                $this->showParameters($value);
            } else if($key == "recipients") {
                $this->showRecipients($value);
            }
        }
        echo "*************************\n";
    }

    public function setMailSetting($setting) {
        $this->mailSetting = $setting;
    }

    public function setSenderInfo($name, $email) {
        $this->senderName = $name;
        $this->senderEmail = $email;
    }

    private function makeSignature($secretKey, $method, $uri, $timestamp, $accessKey) {
        $space = " ";
        $newLine = "\n";
        $hmac = $method.$space.$uri.$newLine.$timestamp.$newLine.$accessKey;
        $signautue = base64_encode(hash_hmac('sha256', $hmac, $secretKey,true));
        // echo "this is signiture : ".$signautue."\n";
        return $signautue;
    }

    public function setParameters($params) {
        $this->postParam["parameters"] = $params;
    }

    public function addRecipient($mail, $name, $type, $parameters) {
        $recipient = array(
            "address" => $mail,
            "name" => $name,
            "type" => $type,
            "parameters" => $parameters
        );
        array_push($this->postParam["recipients"], $recipient);
    }

    public function setRecipients($array) {
        $this->postParam["recipients"] = $array;
    }

    public function makePostParam($templateSid) {
        $this->isPost = false;

        if($this->mailSetting->method == "POST") {
            $this->postParam = array(
                // 광고메일여부 default: false
                "advertising"           => false,
                // 첨부파일ID
                "attachFileIds"         => array(),
                // Email 본문
                "body"                  => "",
                // 개인발송여부 (개인발송 시 참조인, 숨은참조 무시됨) default: true
                "individual"            => false,
                // 치환 파라미터 (수신자별로 적용), ‘치환 ID’ 를 key로, ‘치환 ID에 맵핑되는 값’ 을 value로 가지는 Map 형태의 Object
                "parameters"            => array(),
                "recipients"            => array(),
                // 특정 메일을 모아서 보기 위해 네이버 메일에서 지원하는 기능,
                // 해당 필드에 동일한 값을 입력한 메일들을 모아서 볼 수 있다.
                // (다음의 형태가 되어야 함 : <unique_id@domain.com> )
                "referencesHeader"      => "",
                // 예약 발송 일시 ( 1970년 1월 1일 00:00:00 협정 세계시(UTC) 부터의 경과 시간을 1/1000초로 환산한 정수 ),
                // reservationDateTime 값보다 이 값이 우선 적용된다.
                "reservationUtc"        => "",
                // 다음과 같은 형태의 예약 발송 일시 (‘yyyy-MM-dd HH:mm’ UTC+09:00), reservationUtc 값이 우선한다.
                "reservationDateTime"   => "",
                // 발송자 Email 주소
                "senderAddress"         => $this->senderEmail,
                // 발송자 이름
                "senderName"            => $this->senderName,
                // 첨부파일 등록 시 사용한 임시 요청 ID
                "tempRequestId"         => "",
                // 템플릿 ID
                "templateSid"           => $templateSid,
                // Mail 제목
                "title"                 => "",
            );

            $this->isPost = true;

            $success_code = 201;
        } else {
            $success_code = 200;
            $requestUrl = $this->requestUrl."/requests/".$this->requestId."/status";
        }
    }

    private function getTimestamp() {
        $timestamp = "";
        $microtime = "";
        list($microtime,$timestamp) = explode(' ',microtime());
        $timestamp = $timestamp.substr($microtime, 2, 3);
        return $timestamp;
    }

    private function curlInit($url, $timestamp, $signautue) {
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, $this->isPost);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
        if($this->mailSetting->method == "POST") {
            $postParam = json_encode($this->postParam);
            // echo $postParam."\n";
            curl_setopt($ch, CURLOPT_POSTFIELDS, $postParam);
        }

        $headers = array();
        $headers[] = "X-NCP-APIGW-TIMESTAMP: " .$timestamp;
        $headers[] = "X-NCP-IAM-ACCESS-KEY: " .$this->mailSetting->accessKey;
        $headers[] = "X-NCP-APIGW-SIGNATURE-V2: " .$signautue;
        $headers[] = "content-type: application/json";

        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

        return $ch;
    }

    public function send() {
        try {
            $timestamp = $this->getTimestamp();

            $signautue = $this->makeSignature(
                $this->mailSetting->secretKey,
                $this->mailSetting->method,
                $this->mailSetting->requestUrl,
                $timestamp,
                $this->mailSetting->accessKey
            );

            $url = $this->mailSetting->hostNameUrl.$this->mailSetting->requestUrl;
            // echo $url."\n";

            $ch = $this->curlInit($url, $timestamp, $signautue);
            $response = curl_exec($ch);
            $status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            echo "status_code:".$status_code."\n";
            curl_close ($ch);

            if($status_code == 200) {
                echo $response."\n";
            } else {
                echo "Error 내용:".$response."\n";
            }

        } catch(Exception $E) {
            echo "Response: ". $E->lastResponse . "\n";
        }
    }
}

?>