<?php

require_once "include/api/SugarApi.php";
require_once "modules/ACLRoles/ACLRole.php";
require_once "SP_TemplateFoldersHelper.php";

define("SP_TEMPLATEFOLDER_ACCESSMODE_FULL", 0); // Full access for all users
define("SP_TEMPLATEFOLDER_ACCESSMODE_HIDE", 1); // Hidden for all users
define("SP_TEMPLATEFOLDER_ACCESSMODE_ROLE", 2); // Access by following users and roles

/**
 * Custom REST API endpoints.
 * @author Alexander Logvinenko <alo@celenia.com>
 * @copyright (c) 2016, Celenia Software
 */
class SP_CustomApi extends SugarApi
{

    /**
     * Register rest api endpoints.
     * @return array
     */
    public function registerApiRest()
    {
        return [
            "relatedRoles"              => [
                "reqType"   => "GET",
                "path"      => [ "sp_api", "relatedroles" ],
                "method"    => "retrieveRelatedRoles",
                "shortHelp" => "Retrieve the related roles of the current user."
            ],

            "relatedTemplateFolders"    => [
                "reqType"   => "GET",
                "path"      => [ "sp_api", "relatedtemplatefolders" ],
                "method"    => "retrieveRelatedTemplateFolders",
                "shortHelp" => "Retrieve the related template folders for role."
            ],

            "relatedTemplates"          => [
                "reqType"   => "GET",
                "path"      => [ "sp_api", "relatedtemplates" ],
                "method"    => "retrieveRelatedTemplates",
                "shortHelp" => "Retrieve the related mailing templates for template folder."
            ],

            "unfiledTemplates"          => [
                "reqType"   => "GET",
                "path"      => [ "sp_api", "unfiledtemplates" ],
                "method"    => "retrieveUnfiledTemplates",
                "shortHelp" => "Retrieve the unfiled mailing templates."
            ],

            "updateTemplateFolder"      => [
                "reqType"   => "POST",
                "path"      => [ "sp_api", "updatetemplatefolder" ],
                "method"    => "updateTemplateFolder",
                "shortHelp" => "Update the template folder."
            ]
        ];
    }

    /**
     * Retrieve the related roles for current user.
     * @param SugarApi $api The sugar api instance
     * @param array $args The arguments
     * @return array
     */
    public function retrieveRelatedRoles($api, $args)
    {
        // global $current_user;
        $this->requireArgs($args, [ "id" ]);

        $roles  = ACLRole::getUserRoles($args["id"], false);
        $result = [];

        foreach ($roles as $role) {
            $result[] = [ "id" => $role->id, "name" => $role->name ];
        }

        return $result;
    }

    /**
     * Retrieve the related template folders for the specified role.
     * @param SugarApi $api The sugar api instance
     * @param array $args The arguments
     * @return array
     */
    public function retrieveRelatedTemplateFolders($api, $args)
    {
        // global $log;
        // global $current_user;
        $this->requireArgs($args, [ "id" ]);

        $templateFolderBean = BeanFactory::getBean("SP_TemplateFolders");
        $query              = new SugarQuery();
        $query->from($templateFolderBean);
        $query->select([ "id", "name" ]);
        $query->orderBy("name", "ASC");

        $templateFolders = $query->execute();
        $result          = [];

        foreach ($templateFolders as $templateFolder) {
            $bean               = BeanFactory::retrieveBean("SP_TemplateFolders", $templateFolder["id"]);
            $mailingTemplates   = $bean->get_linked_beans("sp_templatefolders_sp_mailingtemplates", "SP_MailingTemplates");
            $securityRoles      = $bean->get_linked_beans("sp_templatefolders_sp_securityroles", "SP_SecurityRoles");
            $users              = $bean->get_linked_beans("sp_templatefolders_users", "Users");
            $roles              = $this->retrieveRelatedRoles($this, $args);
            $inserted           = false;

            if (sizeof($mailingTemplates) == 0) {
                // If the folder is empty - skip
                continue;
            }

            if ($bean->sp_folderaccessmode == SP_TEMPLATEFOLDER_ACCESSMODE_FULL) {
                // $log->fatal("Template folder full access -> " . $bean->id . ":" . $bean->name . " :=> user id = " . $args["id"]);
                $result[] = [ "id" => $bean->id, "name" => $bean->name ];
                continue;
            }

            if ($bean->sp_folderaccessmode == SP_TEMPLATEFOLDER_ACCESSMODE_HIDE) {
                // Do not add template folder with the following access level...
                // $log->fatal("Template folder hide access -> " . $bean->id . ":" . $bean->name . " :=> user id = " . $args["id"]);
                continue;
            }

            if ($bean->sp_folderaccessmode == SP_TEMPLATEFOLDER_ACCESSMODE_ROLE) {
                // $log->fatal("Template folder role access -> " . $bean->id . ":" . $bean->name . " :=> user id = " . $args["id"]);

                // Add by security roles
                foreach ($securityRoles as $securityRole) {
                    foreach ($roles as $role) {
                        if ($role["id"] == $securityRole->sp_roleid) {
                            // $log->fatal("Template folder role access -> " . $bean->id . ":" . $bean->name . " :=> user id = " . $args["id"] . " -> ADDED BY ROLE");
                            if (!$inserted) {
                                $result[] = ["id" => $bean->id, "name" => $bean->name];
                                $inserted = true;
                            }
                        }
                    }
                }

                // Add by users
                foreach ($users as $user) {
                    if ($user->id == $args["id"]) {
                        // $log->fatal("Template folder role access -> " . $bean->id . ":" . $bean->name . " :=> user id = " . $args["id"] . " -> ADDED BY USER");
                        if (!$inserted) {
                            $result[] = ["id" => $bean->id, "name" => $bean->name];
                            $inserted = true;
                        }
                    }
                }
            }
        }

        return $result;
    }

    /**
     * Retrieve the related templates for the specified folder.
     * @param SugarApi $api The sugar api instance
     * @param array $args The arguments
     * @return array The response
     * @throws SugarApiExceptionMissingParameter
     */
    public function retrieveRelatedTemplates($api, $args)
    {
        $this->requireArgs($args, [ "folder" ]);

        $bean               = BeanFactory::retrieveBean("SP_TemplateFolders", $args["folder"]);
        $mailingTemplates   = $bean->get_linked_beans("sp_templatefolders_sp_mailingtemplates", "SP_MailingTemplates");
        $result             = [];

        foreach ($mailingTemplates as $mailingTemplate) {
            $result[] = [
                "id"        => $mailingTemplate->sp_mailingtemplateid,
                "name"      => $mailingTemplate->name,
                "subject"   => $mailingTemplate->sp_subject,
                "crmblock"  => $mailingTemplate->sp_crmblock
            ];
        }

        return $result;
    }

    /**
     * Retrieve unfiled mailing templates.
     * @param SugarApi $api The sugar api instance
     * @param array $args The arguments
     * @return array The response
     */
    public function retrieveUnfiledTemplates($api, $args)
    {
        $mailingTemplatesBean   = BeanFactory::getBean("SP_MailingTemplates");
        $query                  = new SugarQuery();
        $query->from($mailingTemplatesBean);

        $mailingTemplates   = $query->execute();
        $result             = [];

        foreach ($mailingTemplates as $mailingTemplate) {
            $bean             = BeanFactory::retrieveBean("SP_MailingTemplates", $mailingTemplate["id"]);
            $templateFolders  = $bean->get_linked_beans("sp_templatefolders_sp_mailingtemplates", "SP_TemplateFolders");

            if (sizeof($templateFolders) == 0) {
                $result[] = [
                    "id"        => $mailingTemplate["sp_mailingtemplateid"],
                    "name"      => $mailingTemplate["name"],
                    "subject"   => $mailingTemplate["sp_subject"],
                    "crmblock"  => $mailingTemplate["sp_crmblock"]
                ];
            }
        }

        return $result;
    }

    /**
     * Update the template folder.
     * @param SugarApi $api The sugar api instance
     * @param array $args The arguments
     * @return array The response
     * @throws SugarApiExceptionMissingParameter
     */
    public function updateTemplateFolder($api, $args)
    {
        $this->requireArgs($args, [
            "folder",       // The ID of the template folder
            "name",         // The name of the template folder
            "access",       // The access mode of the template folder
            "templates",    // The related to template folder mailing templates
            "roles",        // The related to template folder security roles
            "users"         // The related to template folder users
        ]);

        $templateFolder = BeanFactory::retrieveBean("SP_TemplateFolders", $args["folder"]);
        $templateFolder->name                   = $args["name"];
        $templateFolder->sp_folderaccessmode    = $args["access"];

        SPTemplateFoldersHelper::updateRelatedMailingTemplates($templateFolder, $args["templates"]);
        SPTemplateFoldersHelper::updateRelatedSecurityRoles($templateFolder, $args["roles"]);
        SPTemplateFoldersHelper::updateRelatedUsers($templateFolder, $args["users"]);

        // Save changes...
        $templateFolder->save();

        return [ "id" => $templateFolder->id ];
    }
}
