<?php

define("MAIL_TMPL_DIR", "../etc/");
define("MAIL_TMPL", "ReserveMail.txt");
define("DEFAULT_MAIL_FROM", "noreply@localhost.localdomain");
define("DEFAULT_SUBJECT", "Notification from CuMAS");
require_once 'cumas_smarty.php';
require_once 'cumas_exception.php';

function sendmailTask($logFacility, $mailTab, $contactTab, $activeUsers)
{
    $mailTmpl = new CuMAS_Smarty(
        ["escape_html" => false, "template_dir" => MAIL_TMPL_DIR]
    );

    /* mb_send_mail用設定 */
    mb_language("japanese");
    mb_internal_encoding("UTF-8");

    // テンプレート置換タグのデータを格納
    $tags = makeTemplateTags($mailTab, $contactTab, $activeUsers);
    $mailTmpl->assign($tags);

    // メールテンプレート解析
    // 第二引数を指定するとフェッチモード
    $mailData = parseMailTemplate($logFacility, $mailTmpl->display(MAIL_TMPL, true));

    // 送信者を判定。送信できる人が誰もいなかったら即終了。
    // これ以上ループしても無意味なため。
    if (!$mailTo = makeMailTo($activeUsers, $mailTab, $contactTab)) {
        CuMAS_Exception::log_s(
            $logFacility,
            __FILE__,
            "All users are inactive."
        );
        return false;
    }

    /* note *
     * 送信できる人がいないというのは、アクティブユーザが誰もいない場合
     * なので、おそらくなにかおかしなことが起こっている。
     * 最低限CuMASの管理者はアクティブのはず（でないとログインできない）
     * (もしくはアクティブユーザ全員にメルアドが設定されていない)
     */

    // それぞれのジョブに対して送信
    $ret = mb_send_mail(
            $mailTo,
            $mailData['subject'],
            $mailData['body'],
            $mailData['options']
    );
    /* *失敗した場合 */
    if ($ret === false) {

        CuMAS_Exception::log_s(
            $logFacility,
            __FILE__,
            "Failed to send mail to=$mailTo"
        );

    }
    return true;
}

//////////////////////////
// ローカル関数
//////////////////////////

/**
 * us_idをもとに、us_nameを取得
 * @arg array
 * @return false string
 */
function getUserById($us_id, $activeUsers)
{
    foreach($activeUsers as $user) {
        if ($us_id === $user["us_id"]) {
            return $user;
        }
    }
    return false;
}

/**
 * 検索結果からテンプレートタグ置換データを整形
 * @arg array
 * @return array $tags
 */
function makeTemplateTags($mailData, $contactData, $activeUsers)
{
    /* 登録者名（登録者のus_name) */
    $tags["operatorname"] = $activeUsers[$mailData["registuser"]][0];

    /* 登録者メールアドレス（登録者のus_mail）*/
    $tags["operatoraddr"] = $activeUsers[$mailData["registuser"]][1];
    
    /* カテゴリ名（ca_name）*/
    $tags["category"] = $contactData["ca_name"];

    /* URLに使うジョブ番号をセット */
    $tags["co_id"] = $contactData["co_id"];

    /* 担当者をセット */
    if ($contactData["co_us_id"] === 0) {
        /*  担当者がいなければnull */
        $tags["user"] = " - ";
    } else {
        if (isset($activeUsers[$contactData["co_us_id"]])) {
            $tags["user"] = $activeUsers[$contactData["co_us_id"]][0];
        } else {
            /* 非アクティブならfalse */
            $tags["user"] = " - ";
        }
    }

    /* 件名（ta_subject）*/
    $tags["subject"] = $mailData["subject"];

    /* 登録日時（更新前のta_post）*/
    $tags["inquiry"]    = $contactData["co_inquiry"]    ?: " - ";

    /* 対応予定日（更新前のta_limit）*/
    $tags["limit"]      = $contactData["co_limit"]      ?: " - ";

    /* メール本文（ta_body）*/
    $tags["body"]       = $mailData["body"];

    /* 備考（ta_comment） */
    $tags["comment"]    = $mailData["comment"] ?: " - ";

    return $tags;
}

/**
 * 1件のジョブから、通知メールの送信先を作成する。
 * 全ユーザのリストをstaticでもつ(必要になったときに1度だけ検索する)
 *
 * @args   array
 * @return string
 **/
function makeMailTo($activeUsers, $mailData, $contactData)
{
    global $config;
    static $allUsersList = "";

    // 担当者がいて、かつアクティブならその人に送信する
    // いなければnull、非アクティブならfalseなのでこの条件でよい
    if ($contactData["co_us_id"] !== NULL) {
        if (isset($activeUsers[$contactData["co_us_id"]])) {
            return $activeUsers[$contactData["co_us_id"]][1];
        }
        return false;
    }

    // 以下、アクティブユーザ全員に送りたい場合

    /*  配列の配列なので素直にimplode()できない */
    foreach ($activeUsers as $tmp_us_id => $user_info) {
        if ($user_info[1]) {
            $tmpList[] = $user_info[1];
        }
    }

    $allUsersList = implode(',', $tmpList);

    // アクティブな人がいなかったらメール送らない
    // もしくはだれもメールアドレスを持ってないとき
    if (empty($allUsersList)) {
        $allUsersList = false;
    }

    return $allUsersList;
}

/**
 * メールテンプレートを解析する。
 * テンプレートにはFromヘッダやSubjectヘッダが記述されるかもしれない
 *
 * @arg string
 * @return array
 */
function parseMailTemplate($logFacility, $tmpl)
{
    // 改行＋改行を探してヘッダ分割
    $parts = explode(PHP_EOL . PHP_EOL, $tmpl, 2);
    if (!isset($parts[1])) {
        // ヘッダが無かったら全部本体
        return [
            'subject' => DEFAULT_SUBJECT,
            'body' => $tmpl,
            'options' => DEFAULT_MAIL_FROM,
        ];
    }

    // ヘッダ解析
    $headers = [
        "from" => "",
        "subject" => "",
        "option" => "",
    ];

    foreach (explode(PHP_EOL, $parts[0]) as $line) {
        $oneHeader = array_map('trim', explode(":", $line, 2));
        if (!isset($oneHeader[1])) {
            throw new CuMAS_Exception(
                "Mail template has wrong header. : '$line'"
            );
        }
        switch (strtolower($oneHeader[0])) {
            case 'subject':
                $headers["subject"] = $oneHeader[1];
                break;

            case 'from':
                $tmpFrom = explode('<', $oneHeader[1], 2);
                /* <>を含まない形式だったらそのままアドレスとして使う */
                if (!isset($tmpFrom[1])) {
                    $headers["from"] = $oneHeader[1];
                    break;
                }

                /* 前半をmimeエンコード */
                $headers["from"] = mb_encode_mimeheader(
                    mb_convert_encoding(trim($tmpFrom[0]), "JIS", "UTF-8")
                );

                $headers["from"] .= " <${tmpFrom[1]}";
                break;

            /* Toヘッダはテンプレートファイルには書かない */
            case 'to':
                CuMAS_Exception::log_s(
                    $logFacility,
                    __FILE__,
                    "Mail template isn't allowed 'To' header."
                );
                break;

            default:
                /* 最後にFromをつけるので改行は全部つけちゃってOK */
                $headers["option"] .= "{$line}\r\n";
                break;
        }
    }       /* ヘッダ解析ここまで */

    return [
        'subject' => $headers['subject'] ?: DEFAULT_SUBJECT,
        'body' => $parts[1],
        'options' => $headers["option"] ."From:".$headers["from"] ?: DEFAULT_MAIL_FROM
    ];
}

/* vim: set filetype=php: */
/* End of file cumascheck.php */
