package io.cattle.platform.iaas.api.auth.impl;

import io.cattle.platform.api.auth.Policy;
import io.cattle.platform.api.pubsub.util.SubscriptionUtils;
import io.cattle.platform.api.pubsub.util.SubscriptionUtils.SubscriptionStyle;
import io.cattle.platform.core.model.Account;
import io.cattle.platform.iaas.api.auth.AchaiusPolicyOptionsFactory;
import io.cattle.platform.iaas.api.auth.AuthorizationProvider;
import io.cattle.platform.iaas.event.IaasEvents;
import io.cattle.platform.util.type.InitializationTask;
import io.cattle.platform.util.type.Priority;
import io.github.ibuildthecloud.gdapi.factory.SchemaFactory;
import io.github.ibuildthecloud.gdapi.factory.impl.SubSchemaFactory;
import io.github.ibuildthecloud.gdapi.request.ApiRequest;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;

public class DefaultAuthorizationProvider implements AuthorizationProvider, InitializationTask, Priority {

    Map<String,SchemaFactory> schemaFactories = new HashMap<String, SchemaFactory>();
    List<SchemaFactory> schemaFactoryList;
    int priority = Priority.DEFAULT;
    AchaiusPolicyOptionsFactory optionsFactory;

    @Override
    public SchemaFactory getSchemaFactory(Account account, ApiRequest request) {
        return schemaFactories.get(account.getKind());
    }

    @Override
    public Policy getPolicy(Account account, ApiRequest request) {
        PolicyOptionsWrapper options = new PolicyOptionsWrapper(optionsFactory.getOptions(account));
        AccountPolicy policy = new AccountPolicy(account, options);

        if ( SubscriptionUtils.getSubscriptionStyle(policy) == SubscriptionStyle.QUALIFIED ) {
            options.setOption(SubscriptionUtils.POLICY_SUBSCRIPTION_QUALIFIER, IaasEvents.ACCOUNT_QUALIFIER);
            options.setOption(SubscriptionUtils.POLICY_SUBSCRIPTION_QUALIFIER_VALUE, Long.toString(account.getId()));
        }

        return policy;
    }

    public static SubscriptionStyle getSubscriptionStyle(Account account, AchaiusPolicyOptionsFactory optionsFactory) {
        Policy tempPolicy = new AccountPolicy(account, optionsFactory.getOptions(account));
        return SubscriptionUtils.getSubscriptionStyle(tempPolicy);
    }


    public List<SchemaFactory> getSchemaFactoryList() {
        return schemaFactoryList;
    }

    @Inject
    public void setSchemaFactoryList(List<SchemaFactory> schemaFactoryList) {
        this.schemaFactoryList = schemaFactoryList;
    }

    @Override
    public void start() {
        for ( SchemaFactory factory : schemaFactoryList ) {
            if ( factory instanceof SubSchemaFactory ) {
                ((SubSchemaFactory)factory).init();
            }
            schemaFactories.put(factory.getId(), factory);
        }
    }

    @Override
    public void stop() {
    }

    @Override
    public int getPriority() {
        return priority;
    }

    public void setPriority(int priority) {
        this.priority = priority;
    }

    public AchaiusPolicyOptionsFactory getOptionsFactory() {
        return optionsFactory;
    }

    @Inject
    public void setOptionsFactory(AchaiusPolicyOptionsFactory optionsFactory) {
        this.optionsFactory = optionsFactory;
    }

}

@@ -843,16 +843,74 @@
 nject;%0A%0A
+import org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;%0A%0A
 public c
@@ -1009,16 +1009,206 @@
 rity %7B%0A%0A
+    public static final String ACCOUNT_SCHEMA_FACTORY_NAME = %22accountSchemaFactoryName%22;%0A%0A    private static final Logger log = LoggerFactory.getLogger(DefaultAuthorizationProvider.class);%0A%0A
     Map%3C
@@ -1420,32 +1420,32 @@
 %0A%0A    @Override%0A
-
     public Schem
@@ -1501,32 +1501,413 @@
 uest request) %7B%0A
+        Object name = request.getAttribute(ACCOUNT_SCHEMA_FACTORY_NAME);%0A        if ( name != null ) %7B%0A            SchemaFactory schemaFactory = schemaFactories.get(name.toString());%0A            if ( schemaFactory == null ) %7B%0A                log.error(%22Failed to find schema factory %5B%7B%7D%5D%22, name);%0A            %7D else %7B%0A                return schemaFactory;%0A            %7D%0A        %7D%0A%0A
         return s

add override for account schema choice