/*
 * 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
 *
 * @author Gerhard Petracek
 * @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);
    }
}
