/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
 *
 * 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 com.android.ide.eclipse.adt.internal.resources.manager;

import com.android.SdkConstants;
import com.android.annotations.NonNull;
import com.android.ide.common.rendering.api.ResourceValue;
import com.android.ide.common.resources.IntArrayWrapper;
import com.android.ide.common.resources.ResourceFolder;
import com.android.ide.common.resources.ResourceItem;
import com.android.ide.common.resources.ResourceRepository;
import com.android.ide.common.resources.configuration.FolderConfiguration;
import com.android.ide.eclipse.adt.internal.sdk.ProjectState;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.ide.eclipse.adt.io.IFolderWrapper;
import com.android.io.IAbstractFolder;
import com.android.resources.ResourceType;
import com.android.util.Pair;

import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;

import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

/**
 * Represents the resources of a project.
 * On top of the regular {@link ResourceRepository} features it provides:
 *<ul>
 *<li>configured resources contain the resources coming from the libraries.</li>
 *<li>resolution to and from resource integer (compiled value in R.java).</li>
 *<li>handles resource integer for non existing values of type ID. This is used when rendering.</li>
 *<li>layouts that have no been saved yet. This is handled by generating dynamic IDs
 *       on the fly.</li>
 *</ul>
 */
@SuppressWarnings("deprecation")
public class ProjectResources extends ResourceRepository {
    // project resources are defined as 0x7FXX#### where XX is the resource type (layout, drawable,
    // etc...). Using FF as the type allows for 255 resource types before we get a collision
    // which should be fine.
    private final static int DYNAMIC_ID_SEED_START = 0x7fff0000;

    /** Map of (name, id) for resources of type {@link ResourceType#ID} coming from R.java */
    private Map<ResourceType, Map<String, Integer>> mResourceValueMap;
    /** Map of (id, [name, resType]) for all resources coming from R.java */
    private Map<Integer, Pair<ResourceType, String>> mResIdValueToNameMap;
    /** Map of (int[], name) for styleable resources coming from R.java */
    private Map<IntArrayWrapper, String> mStyleableValueToNameMap;

    private final DynamicIdMap mDynamicIdMap = new DynamicIdMap(DYNAMIC_ID_SEED_START);

    private final IProject mProject;

    public static ProjectResources create(IProject project) {
        IFolder resFolder = project.getFolder(SdkConstants.FD_RESOURCES);

        return new ProjectResources(project, new IFolderWrapper(resFolder));
    }

    /**
     * Makes a ProjectResources for a given <var>project</var>.
     * @param project the project.
     */
    private ProjectResources(IProject project, IAbstractFolder resFolder) {
        super(resFolder, false /*isFrameworkRepository*/);
        mProject = project;
    }

    /**
     * Returns the resources values matching a given {@link FolderConfiguration}, this will
     * include library dependency.
     *
     * @param referenceConfig the configuration that each value must match.
     * @return a map with guaranteed to contain an entry for each {@link ResourceType}
     */
    @Override
    @NonNull
    public Map<ResourceType, Map<String, ResourceValue>> getConfiguredResources(
            @NonNull FolderConfiguration referenceConfig) {
        ensureInitialized();

        Map<ResourceType, Map<String, ResourceValue>> resultMap =
            new EnumMap<ResourceType, Map<String, ResourceValue>>(ResourceType.class);

        // if the project contains libraries, we need to add the libraries resources here
        // so that they are accessible to the layout rendering.
        if (mProject != null) {
            ProjectState state = Sdk.getProjectState(mProject);
            if (state != null) {
                List<IProject> libraries = state.getFullLibraryProjects();

                ResourceManager resMgr = ResourceManager.getInstance();

                // because aapt put all the library in their order in this array, the first
                // one will have priority over the 2nd one. So it's better to loop in the inverse
                // order and fill the map with resources that will be overwritten by higher
                // priority resources
                for (int i = libraries.size() - 1 ; i >= 0 ; i--) {
                    IProject library = libraries.get(i);

                    ProjectResources libRes = resMgr.getProjectResources(library);
                    if (libRes != null) {
                        // get the library resources, and only the library, not the dependencies
                        // so call doGetConfiguredResources() directly.
                        Map<ResourceType, Map<String, ResourceValue>> libMap =
                                libRes.doGetConfiguredResources(referenceConfig);

                        // we don't want to simply replace the whole map, but instead merge the
                        // content of any sub-map
                        for (Entry<ResourceType, Map<String, ResourceValue>> libEntry :
                                libMap.entrySet()) {

                            // get the map currently in the result map for this resource type
                            Map<String, ResourceValue> tempMap = resultMap.get(libEntry.getKey());
                            if (tempMap == null) {
                                // since there's no current map for this type, just add the map
                                // directly coming from the library resources
                                resultMap.put(libEntry.getKey(), libEntry.getValue());
                            } else {
                                // already a map for this type. add the resources from the
                                // library, this will override existing value, which is why
                                // we loop in a specific library order.
                                tempMap.putAll(libEntry.getValue());
                            }
                        }
                    }
                }
            }
        }

        // now the project resources themselves.
        Map<ResourceType, Map<String, ResourceValue>> thisProjectMap =
                doGetConfiguredResources(referenceConfig);

        // now merge the maps.
        for (Entry<ResourceType, Map<String, ResourceValue>> entry : thisProjectMap.entrySet()) {
            ResourceType type = entry.getKey();
            Map<String, ResourceValue> typeMap = resultMap.get(type);
            if (typeMap == null) {
                resultMap.put(type, entry.getValue());
            } else {
                typeMap.putAll(entry.getValue());
            }
        }

        return resultMap;
    }

    /**
     * Returns the {@link ResourceFolder} associated with a {@link IFolder}.
     * @param folder The {@link IFolder} object.
     * @return the {@link ResourceFolder} or null if it was not found.
     *
     * @see ResourceRepository#getResourceFolder(com.android.io.IAbstractFolder)
     */
    public ResourceFolder getResourceFolder(IFolder folder) {
        return getResourceFolder(new IFolderWrapper(folder));
    }

    /**
     * Resolves a compiled resource id into the resource name and type
     * @param id the resource integer id.
     * @return a {@link Pair} of 2 strings { name, type } or null if the id could not be resolved
     */
    public Pair<ResourceType, String> resolveResourceId(int id) {
        Pair<ResourceType, String> result = null;
        if (mResIdValueToNameMap != null) {
            result = mResIdValueToNameMap.get(id);
        }

        if (result == null) {
            synchronized (mDynamicIdMap) {
                result = mDynamicIdMap.resolveId(id);
            }
        }

        return result;
    }

    /**
     * Resolves a compiled styleable id of type int[] into the styleable name.
     */
    public String resolveStyleable(int[] id) {
        if (mStyleableValueToNameMap != null) {
            mWrapper.set(id);
            return mStyleableValueToNameMap.get(mWrapper);
        }

        return null;
    }

    /**
     * Returns the integer id of a resource given its type and name.
     * <p/>If the resource is of type {@link ResourceType#ID} and does not exist in the
     * internal map, then new id values are dynamically generated (and stored so that queries
     * with the same names will return the same value).
     */
    public Integer getResourceId(ResourceType type, String name) {
        Integer result = null;
        if (mResourceValueMap != null) {
            Map<String, Integer> map = mResourceValueMap.get(type);
            if (map != null) {
                result = map.get(name);
            }
        }

        if (result == null) {
            synchronized (mDynamicIdMap) {
                result = mDynamicIdMap.getId(type, name);
            }
        }

        return result;
    }

    /**
     * Resets the list of dynamic Ids. This list is used by
     * {@link #getResourceId(String, String)} when the resource query is an ID that doesn't
     * exist (for example for ID automatically generated in layout files that are not saved yet.)
     * <p/>This method resets those dynamic ID and must be called whenever the actual list of IDs
     * change.
     */
    public void resetDynamicIds() {
        synchronized (mDynamicIdMap) {
            mDynamicIdMap.reset(DYNAMIC_ID_SEED_START);
        }
    }

    @Override
    @NonNull
    protected ResourceItem createResourceItem(@NonNull String name) {
        return new ResourceItem(name);
    }

    /**
     * Sets compiled resource information.
     *
     * @param resIdValueToNameMap a map of compiled resource id to resource name.
     *    The map is acquired by the {@link ProjectResources} object.
     * @param styleableValueMap a map of (int[], name) for the styleable information. The map is
     *    acquired by the {@link ProjectResources} object.
     * @param resourceValueMap a map of (name, id) for resources of type {@link ResourceType#ID}.
     *    The list is acquired by the {@link ProjectResources} object.
     */
    void setCompiledResources(Map<Integer, Pair<ResourceType, String>> resIdValueToNameMap,
            Map<IntArrayWrapper, String> styleableValueMap,
            Map<ResourceType, Map<String, Integer>> resourceValueMap) {
        mResourceValueMap = resourceValueMap;
        mResIdValueToNameMap = resIdValueToNameMap;
        mStyleableValueToNameMap = styleableValueMap;

        resetDynamicIds();
    }
}
