/*
 * 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.beanval.storage;

import org.apache.myfaces.extensions.validator.util.GroupUtils;
import org.apache.myfaces.extensions.validator.internal.UsageInformation;
import static org.apache.myfaces.extensions.validator.internal.UsageCategory.INTERNAL;

import javax.faces.context.FacesContext;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.ArrayList;

/**
 * storage implementation for model-validation entries
 *
 * @since x.x.3
 */
@UsageInformation(INTERNAL)
public class DefaultModelValidationStorage implements ModelValidationStorage
{
    private Map<String, List<ModelValidationEntry>> modelValidationEntries =
            new HashMap<String, List<ModelValidationEntry>>();

    private List<String> componentsOfRequest = new ArrayList<String>();

    public void addModelValidationEntry(ModelValidationEntry modelValidationEntry)
    {
        String clientId = getCurrentClientId(modelValidationEntry);

        List<ModelValidationEntry> modelValidationEntryList = resolveModelValidationEntryList(
                modelValidationEntry, clientId);

        addModelValidationEntry(modelValidationEntryList, modelValidationEntry);
    }

    private String getCurrentClientId(ModelValidationEntry modelValidationEntry)
    {
        String clientId = null;

        if(modelValidationEntry.getComponent() != null)
        {
            clientId = modelValidationEntry.getComponent().getClientId(FacesContext.getCurrentInstance());

            if(!this.componentsOfRequest.contains(clientId))
            {
                this.componentsOfRequest.add(clientId);
            }
        }
        return clientId;
    }

    private List<ModelValidationEntry> resolveModelValidationEntryList(
            ModelValidationEntry modelValidationEntry, String clientId)
    {
        List<ModelValidationEntry> modelValidationEntryList =
                this.modelValidationEntries.get(GroupUtils.getGroupKey(
                        modelValidationEntry.getViewId(), clientId));

        if(modelValidationEntryList == null)
        {
            modelValidationEntryList = new ArrayList<ModelValidationEntry>();
            this.modelValidationEntries.put(GroupUtils.getGroupKey(
                    modelValidationEntry.getViewId(), clientId), modelValidationEntryList);
        }
        return modelValidationEntryList;
    }

    private void addModelValidationEntry(
            List<ModelValidationEntry> modelValidationEntryList, ModelValidationEntry modelValidationEntry)
    {
        if(!modelValidationEntryList.contains(modelValidationEntry))
        {
            modelValidationEntryList.add(modelValidationEntry);
        }
    }

    public List<ModelValidationEntry> getModelValidationEntriesToValidate()
    {
        String viewId = FacesContext.getCurrentInstance().getViewRoot().getViewId();
        List<ModelValidationEntry> result = new ArrayList<ModelValidationEntry>();

        addEntriesForComponents(viewId, result);

        addEntriesForPage(viewId, result);

        return result;
    }

    private void addEntriesForComponents(String viewId, List<ModelValidationEntry> result)
    {
        for(String currentClientId : this.componentsOfRequest)
        {
            result.addAll(getModelValidationEntries(viewId, currentClientId));
        }
    }

    private void addEntriesForPage(String viewId, List<ModelValidationEntry> result)
    {
        result.addAll(getModelValidationEntries(viewId));
    }

    private List<ModelValidationEntry> buildModelValidationEntryList(
            String key, Map<String, List<ModelValidationEntry>> groupStorage)
    {
        List<ModelValidationEntry> list;

        if(key != null && key.endsWith("*"))
        {
            list = new ArrayList<ModelValidationEntry>();
            for(Map.Entry<String,List<ModelValidationEntry>> entry : groupStorage.entrySet())
            {
                if(entry.getKey().substring(0, entry.getKey().indexOf("@"))
                        .equals(key.substring(0, key.indexOf("@"))))
                {
                    list.addAll(entry.getValue());
                }
            }
            return list;
        }

        list = groupStorage.get(key);
        return (list != null) ? list : new ArrayList<ModelValidationEntry>();
    }

    private List<ModelValidationEntry> getModelValidationEntries(String viewId)
    {
        return getModelValidationEntries(viewId, null);
    }

    private List<ModelValidationEntry> getModelValidationEntries(String viewId, String clientId)
    {
        if(this.modelValidationEntries.size() < 1)
        {
            return new ArrayList<ModelValidationEntry>();
        }

        //add found groups
        String key;
        List<ModelValidationEntry> resultListForPage = null;

        if(!"*".equals(clientId))
        {
            key = GroupUtils.getGroupKey(viewId, null);
            resultListForPage =
                    buildModelValidationEntryList(key, this.modelValidationEntries);
        }

        key = GroupUtils.getGroupKey(viewId, clientId);
        List<ModelValidationEntry> resultListForComponent =
                buildModelValidationEntryList(key, this.modelValidationEntries);

        if(resultListForPage == null || resultListForPage.isEmpty())
        {
            return resultListForComponent;
        }
        else if(resultListForComponent.isEmpty())
        {
            return resultListForPage;
        }

        return mergeResults(resultListForPage, resultListForComponent);
    }

    private List<ModelValidationEntry> mergeResults(
            List<ModelValidationEntry> resultListForPage, List<ModelValidationEntry> resultListForComponent)
    {
        List<ModelValidationEntry> mergedResult = new ArrayList<ModelValidationEntry>();
        mergedResult.addAll(resultListForPage);
        mergedResult.addAll(resultListForComponent);
        return mergedResult;
    }
}
