/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.myfaces.extensions.validator.core.storage;

import org.apache.myfaces.extensions.validator.core.factory.ClassMappingFactory;
import org.apache.myfaces.extensions.validator.core.factory.AbstractNameMapperAwareFactory;
import org.apache.myfaces.extensions.validator.core.mapper.NameMapper;
import org.apache.myfaces.extensions.validator.core.initializer.configuration.StaticConfigurationNames;
import org.apache.myfaces.extensions.validator.core.initializer.configuration.StaticConfiguration;
import org.apache.myfaces.extensions.validator.core.initializer.configuration.StaticConfigurationEntry;
import org.apache.myfaces.extensions.validator.core.ExtValContext;
import org.apache.myfaces.extensions.validator.internal.UsageInformation;
import org.apache.myfaces.extensions.validator.util.ClassUtils;
import static org.apache.myfaces.extensions.validator.internal.UsageCategory.INTERNAL;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.logging.Logger;

/**
 * default implementation for storage-manager creation and caching
 *
 * @since x.x.3
 */
@UsageInformation(INTERNAL)
public class DefaultStorageManagerFactory extends AbstractNameMapperAwareFactory<Class>
        implements ClassMappingFactory<Class, StorageManager>, StorageManagerHolder
{
    protected final Logger logger = Logger.getLogger(getClass().getName());

    private boolean lazyStaticMappingApplied = false;
    private List<NameMapper<Class>> nameMapperList = new CopyOnWriteArrayList<NameMapper<Class>>();
    private Map<Class, StorageManager> storageTypeToStorageManagerMap = new ConcurrentHashMap<Class, StorageManager>();

    public DefaultStorageManagerFactory()
    {
        logger.fine(getClass().getName() + " instantiated");

        setStorageManager(RendererProxyStorage.class,
                new DefaultRendererProxyStorageManager(), false);
        setStorageManager(GroupStorage.class,
                new DefaultGroupStorageManager(), false);
        setStorageManager(MetaDataStorage.class,
                new DefaultMetaDataStorageManager(), false);
        setStorageManager(FacesMessageStorage.class,
                new DefaultFacesMessageStorageManager(), false);
        setStorageManager(PropertyStorage.class,
                new DefaultPropertyStorageManager(), false);
        setStorageManager(RendererInterceptorPropertyStorage.class,
                new DefaultRendererInterceptorPropertyStorageManager(), false);
        setStorageManager(ViolationSeverityInterpreterStorage.class,
                new DefaultViolationSeverityInterpreterStorageManager(), false);
        setStorageManager(MappedConstraintSourceStorage.class,
                new DefaultMappedConstraintSourceStorageManager(), false);

        setStorageManager(FacesInformationStorage.class,
                new DefaultFacesInformationStorageManager(), false);
    }

    public StorageManager create(Class storageType)
    {
        if (!this.lazyStaticMappingApplied)
        {
            initStaticMappings();
        }

        StorageManager storageManager;
        String storageManagerName;
        //null -> use name mappers
        for (NameMapper<Class> nameMapper : this.nameMapperList)
        {
            storageManagerName = nameMapper.createName(storageType);

            if (storageManagerName == null)
            {
                continue;
            }

            storageManager = (StorageManager)ClassUtils.tryToInstantiateClassForName(storageManagerName);

            if (storageManager != null)
            {
                addMapping(storageType, storageManager);
                return storageManager;
            }
        }
        return getStorageManager(storageType);
    }

    private synchronized void addMapping(Class storageType, StorageManager storageManager)
    {
        boolean isValidEntry = true;
        if(storageType == null)
        {
            isValidEntry = false;
            this.logger.severe("you tried to add an invalid storage type");
        }

        if(storageManager == null)
        {
            isValidEntry = false;
            this.logger.severe("you tried to add an invalid storage manager");
        }

        if(!isValidEntry)
        {
            return;
        }

        setStorageManager(storageType, storageManager, true);
    }

    private void initStaticMappings()
    {
        this.lazyStaticMappingApplied = true;

        //setup internal static mappings
        for (StaticConfiguration<String, String> staticConfig :
            ExtValContext.getContext().getStaticConfiguration(
                StaticConfigurationNames.STORAGE_TYPE_TO_STORAGE_MANAGER_CONFIG))
        {
            setupMappings(staticConfig.getMapping());
        }
    }

    private void setupMappings(List<StaticConfigurationEntry<String, String>> mappings)
    {
        for(StaticConfigurationEntry<String, String> mapping : mappings)
        {
            addMapping(ClassUtils.tryToLoadClassForName(mapping.getSource()),
                    (StorageManager)ClassUtils.tryToInstantiateClassForName(mapping.getTarget()));
        }
    }

    protected List<NameMapper<Class>> getNameMapperList()
    {
        return this.nameMapperList;
    }

    public void setStorageManager(Class storageType, StorageManager storageManager, boolean override)
    {
        if(!this.storageTypeToStorageManagerMap.containsKey(storageType) ||
                (this.storageTypeToStorageManagerMap.containsKey(storageType) && override))
        {

            logger.finest("adding type to storage-manager mapping: "
                + storageType.getName() + " -> " + storageManager.getClass().getName());

            this.storageTypeToStorageManagerMap.put(storageType, storageManager);
        }
    }

    public StorageManager getStorageManager(Class type)
    {
        return this.storageTypeToStorageManagerMap.get(type);
    }
}
