<?php

namespace TdyAdmins;

use TdyAdmins\Model\Admin;
use Zend\Authentication\Adapter as AuthAdapter;
use Zend\Authentication\Storage;
use Zend\Authentication\AuthenticationService;
use Zend\Db\Adapter\Adapter as DbAdapter;
use Zend\Db\ResultSet\HydratingResultSet;
use Zend\Db\TableGateway\TableGateway;
use Zend\Di\ServiceLocatorInterface;
use Zend\ModuleManager\Feature\AutoloaderProviderInterface;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
use Zend\ModuleManager\Feature\ServiceProviderInterface;
use Zend\ModuleManager\Feature\ViewHelperProviderInterface;
use Zend\Session;
use Zend\View\HelperPluginManager;

class Module implements AutoloaderProviderInterface, ConfigProviderInterface, ServiceProviderInterface, ViewHelperProviderInterface
{

    public function getConfig()
    {
        $general = include __DIR__ . '/config/general.php';
        $db      = include __DIR__ . '/config/db.php';

        return array_merge($general, $db);
    }

    public function getAutoloaderConfig()
    {
        return [
            'Zend\Loader\StandardAutoloader' => [
                'namespaces' => [
                    __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
                ],
            ],
        ];
    }

    public function getViewHelperConfig()
    {
        return [
            'factories' => [
                'currentAdmin' => function ($hpm) {
                    /** @var HelperPluginManager $hpm */
                    $locator = $hpm->getServiceLocator();
                    $admin   = new View\Helper\CurrentAdmin();
                    $admin->setServiceLocator($locator);

                    return $admin;
                },
            ],
        ];
    }

    public function getServiceConfig()
    {
        return [
            'factories' => [
                'CurrentAdmin' => function ($sm) {
                    $session = new Session\Container(SESSION_CONTAINER);
                    if (isset($session->user)) {
                        /**
                         * @var ServiceLocatorInterface $sm
                         * @var Admin                   $admin
                         */
                        $admin = $sm->get('TdyAdmins\Table\Admins')->get($session->user->id);

                        return $admin;
                    } else {
                        return new Admin();
                    }
                },
                'TdyAdmins\Table\Admins' => function ($sm) {
                    /**
                     * @var ServiceLocatorInterface $sm
                     * @var DbAdapter               $dbAdapter
                     */
                    $dbAdapter = $sm->get('db-01');
                    $tableName = $sm->get('config')['mappings']['tables']['admins']['name'];
                    $columns   = $sm->get('config')['mappings']['tables']['admins']['columns'];
                    $logger    = $sm->get('Logger');

                    $resultSetProto = new HydratingResultSet();
                    $resultSetProto->setObjectPrototype(new Model\Admin());
                    $tableGateway = new TableGateway($tableName, $dbAdapter, null, $resultSetProto);
                    $table        = new Table\Admins($tableGateway, $columns);
                    $table->setLogger($logger);

                    return $table;
                },
                'AuthStorage' => function () {
                    return new Storage\Session('auth');
                },
                'AuthService\Db' => function ($sm) {
                    /**
                     * @var ServiceLocatorInterface $sm
                     * @var DbAdapter               $dbAdapter
                     */
                    $dbAdapter = $sm->get('db-01');
                    $tableName = $sm->get('config')['mappings']['tables']['admins']['name'];

                    /** @var Storage\Session $storage */
                    $storage = $sm->get('AuthStorage');

                    $dbTableAuthAdapter = new Authentication\Adapter\DbTable\BcryptTreatment($dbAdapter, $tableName, 'username', 'password', 'is_active = 1');
                    $authService        = new AuthenticationService();
                    $authService->setAdapter($dbTableAuthAdapter);
                    $authService->setStorage($storage);

                    return $authService;
                },

            ],
        ];
    }

}