<?php
use ZF\MvcAuth\Factory\AuthenticationHttpAdapterFactory;
use ZF\MvcAuth\Factory\AuthenticationOAuth2AdapterFactory;

class CompositeAdapterFactory
{
    public function __invoke($services)
    {
        $config = $services->get('Config');
        $adapters = [];

        /*
         * You could put the key somewhere else. The idea, though, is that each
         * named adapter matches a key under zf-mvc-auth.authentication.adapters. The 
         * primary problem with this approach is that you'll get two instances
         * for adapters you attach to the composite adapter. One alternative is
         * to use the approach in ZF\MvcAuth\Factory\AuthenticationAdapterDelegatorFactory
         * and define the configuration for the attached adapters within this
         * array, and instantiate them here only. Of course, that means you can
         * only configure those adapters manually.
         */
        if (isset($config['zf-mvc-auth']['authentication']['composite'])
            && is_array($config['zf-mvc-auth']['authentication']['composite'])
        ) {
            $adapters = $config['zf-mvc-auth']['authentication']['composite'];
        }

        $composite = new CompositeAdapter();

        foreach ($adapters as $adapterName) {
            $adapter = $this->getAdapter(
                $adapterName,
                $config['zf-mvc-auth']['authentication']['adapters'],
                $services
            );
            if (! $adapter) {
                continue;
            }
            $composite->attach($adapter);
        }

        return $composite;
    }

    private function getAdapter($adapterName, array $config, $services)
    {
        if (! isset $config[$adapterName]
            || ! isset($config[$adapterName]['adapter'])
            || ! is_string($config[$adapterName]['adapter'])
        ) {
            return false;
        }
        
        $config = $config[$adapterName];
        switch ($config['adapter']) {
            case 'ZF\MvcAuth\Authentication\HttpAdapter':
                return AuthenticationHttpAdapterFactory::factory($adapterName, $config, $services);
            case 'ZF\MvcAuth\Authentication\OAuth2Adapter':
                return AuthenticationOAuth2AdapterFactory::factory($adapterName, $config, $services);
            default:
                return false;
        }
    }
}