/*
 * 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 IntArrayWrapper mWrapper = new IntArrayWrapper(null);
    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();
    }
}
