<?php

namespace IntellexApps\PHP\UploadFile\Domain\Service;

use IntellexApps\PHP\UploadFile\Domain\Exception\FileSystem\DirectoryAlreadyExistsException;
use IntellexApps\PHP\UploadFile\Domain\Exception\FileSystem\DirectoryDoesntExistException;
use IntellexApps\PHP\UploadFile\Domain\Exception\FileSystem\DirectoryNotWritableException;
use IntellexApps\PHP\UploadFile\Domain\Exception\FileSystem\FileAlreadyExistsException;
use IntellexApps\PHP\UploadFile\Domain\Exception\FileSystem\FileNotFoundException;
use IntellexApps\PHP\UploadFile\Domain\Exception\FileSystem\InvalidPathException;
use IntellexApps\PHP\UploadFile\Domain\Exception\UploadFileException;
use IntellexApps\PHP\UploadFile\Util\Configuration;
use IntellexApps\PHP\UploadFile\Util\Inflector;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use SuperClosure\Serializer;

class HookService extends BaseService
{
    const HOOK_BEFORE_LIST = 'before_list';
    const HOOK_AFTER_LIST = 'after_list';

    const HOOK_BEFORE_UPLOAD = 'before_upload';
    const HOOK_AFTER_UPLOAD = 'after_upload';

    const HOOK_BEFORE_MOVE = 'before_move';
    const HOOK_AFTER_MOVE = 'after_move';

    const HOOK_BEFORE_COPY = 'before_copy';
    const HOOK_AFTER_COPY = 'after_copy';

    const HOOK_BEFORE_CREATE = 'before_create';
    const HOOK_AFTER_CREATE = 'after_create';

    const HOOK_BEFORE_DELETE = 'before_delete';
    const HOOK_AFTER_DELETE = 'after_delete';

    const HOOK_BEFORE_RENAME = 'before_rename';
    const HOOK_AFTER_RENAME = 'after_rename';

    const HOOK_BEFORE_VIEW = 'before_view';
    const HOOK_AFTER_VIEW = 'after_view';

    var $hooks = [];

    /**
     * Load hooks
     *
     * @param $hooks
     */
    public function loadHooks($hooks)
    {
        $serializer = new Serializer();
        foreach($hooks as $type => $actualHooks) {
            $this->hooks[$type] = [];

            foreach($actualHooks as $actualHook) {
                $this->hooks[$type][] = $serializer->unserialize($actualHook);
            }
        }
    }

    /**
     * Trigger hook
     *
     * @param $hookName
     * @return bool
     * @throws \Exception
     */
    public function triggerHook($hookName)
    {
        $arguments = func_get_args();

        array_shift($arguments);

        if(isset($this->hooks[$hookName])) {
            foreach($this->hooks[$hookName] as $hook) {
                $result = call_user_func_array($hook, $arguments);

                // Hook should return true if all is OK
                // It should throw exception otherwise, this is just precaution
                if($result !== TRUE) {
                    throw new \Exception(__('Hook %s failed!!!', $hookName));
                }
            }
        }

        // Return true if all ok
        return true;

    }
}
