/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed 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 com.android.ide.common.resources;


import com.android.SdkConstants;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.io.IAbstractFile;
import com.android.io.IAbstractFolder;
import com.android.resources.ResourceType;
import com.android.utils.ILogger;
import com.google.common.base.Charsets;

import org.kxml2.io.KXmlParser;
import org.xmlpull.v1.XmlPullParser;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;

/**
 * Framework resources repository.
 *
 * This behaves the same as {@link ResourceRepository} except that it differentiates between
 * resources that are public and non public.
 * {@link #getResources(ResourceType)} and {@link #hasResourcesOfType(ResourceType)} only return
 * public resources. This is typically used to display resource lists in the UI.
 *
 * {@link #getConfiguredResources(com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration)}
 * returns all resources, even the non public ones so that this can be used for rendering.
 */
public class FrameworkResources extends ResourceRepository {

    /**
     * Map of {@link ResourceType} to list of items. It is guaranteed to contain a list for all
     * possible values of ResourceType.
     */
    protected final Map<ResourceType, List<ResourceItem>> mPublicResourceMap =
        new EnumMap<ResourceType, List<ResourceItem>>(ResourceType.class);

    public FrameworkResources(@NonNull IAbstractFolder resFolder) {
        super(resFolder, true /*isFrameworkRepository*/);
    }

    /**
     * Returns a {@link Collection} (always non null, but can be empty) of <b>public</b>
     * {@link ResourceItem} matching a given {@link ResourceType}.
     *
     * @param type the type of the resources to return
     * @return a collection of items, possible empty.
     */
    @Override
    @NonNull
    public List<ResourceItem> getResourceItemsOfType(@NonNull ResourceType type) {
        return mPublicResourceMap.get(type);
    }

    /**
     * Returns whether the repository has <b>public</b> resources of a given {@link ResourceType}.
     * @param type the type of resource to check.
     * @return true if the repository contains resources of the given type, false otherwise.
     */
    @Override
    public boolean hasResourcesOfType(@NonNull ResourceType type) {
        return mPublicResourceMap.get(type).size() > 0;
    }

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

    /**
     * Reads the public.xml file in data/res/values/ for a given resource folder and builds up
     * a map of public resources.
     *
     * This map is a subset of the full resource map that only contains framework resources
     * that are public.
     *
     * @param resFolder The root folder of the resources
     * @param logger a logger to report issues to
     */
    public void loadPublicResources(@Nullable ILogger logger) {
        IAbstractFolder valueFolder = getResFolder().getFolder(SdkConstants.FD_RES_VALUES);
        if (valueFolder.exists() == false) {
            return;
        }

        IAbstractFile publicXmlFile = valueFolder.getFile("public.xml"); //$NON-NLS-1$
        if (publicXmlFile.exists()) {
            Reader reader = null;
            try {
                reader = new BufferedReader(new InputStreamReader(publicXmlFile.getContents(),
                        Charsets.UTF_8));
                KXmlParser parser = new KXmlParser();
                parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
                parser.setInput(reader);

                ResourceType lastType = null;
                String lastTypeName = "";
                while (true) {
                    int event = parser.next();
                    if (event == XmlPullParser.START_TAG) {
                        // As of API 15 there are a number of "java-symbol" entries here
                        if (!parser.getName().equals("public")) { //$NON-NLS-1$
                            continue;
                        }

                        String name = null;
                        String typeName = null;
                        for (int i = 0, n = parser.getAttributeCount(); i < n; i++) {
                            String attribute = parser.getAttributeName(i);

                            if (attribute.equals("name")) { //$NON-NLS-1$
                                name = parser.getAttributeValue(i);
                                if (typeName != null) {
                                    // Skip id attribute processing
                                    break;
                                }
                            } else if (attribute.equals("type")) { //$NON-NLS-1$
                                typeName = parser.getAttributeValue(i);
                            }
                        }

                        if (name != null && typeName != null) {
                            ResourceType type = null;
                            if (typeName.equals(lastTypeName)) {
                                type = lastType;
                            } else {
                                type = ResourceType.getEnum(typeName);
                                lastType = type;
                                lastTypeName = typeName;
                            }
                            if (type != null) {
                                ResourceItem match = null;
                                Map<String, ResourceItem> map = mResourceMap.get(type);
                                if (map != null) {
                                    match = map.get(name);
                                }

                                if (match != null) {
                                    List<ResourceItem> publicList = mPublicResourceMap.get(type);
                                    if (publicList == null) {
                                        // Pick initial size for the list to hold the public
                                        // resources. We could just use map.size() here,
                                        // but they're usually much bigger; for example,
                                        // in one platform version, there are 1500 drawables
                                        // and 1200 strings but only 175 and 25 public ones
                                        // respectively.
                                        int size;
                                        switch (type) {
                                            case STYLE: size = 500; break;
                                            case ATTR: size = 1000; break;
                                            case DRAWABLE: size = 200; break;
                                            case ID: size = 50; break;
                                            case LAYOUT:
                                            case COLOR:
                                            case STRING:
                                            case ANIM:
                                            case INTERPOLATOR:
                                                size = 30;
                                                break;
                                            default:
                                                size = 10;
                                                break;
                                        }
                                        publicList = new ArrayList<ResourceItem>(size);
                                        mPublicResourceMap.put(type, publicList);
                                    }

                                    publicList.add(match);
                                } else {
                                    // log that there's a public resource that doesn't actually
                                    // exist?
                                }
                            } else {
                                // log that there was a reference to a typo that doesn't actually
                                // exist?
                            }
                        }
                    } else if (event == XmlPullParser.END_DOCUMENT) {
                        break;
                    }
                }
            } catch (Exception e) {
                if (logger != null) {
                    logger.error(e, "Can't read and parse public attribute list");
                }
            } finally {
                if (reader != null) {
                    try {
                        reader.close();
                    } catch (IOException e) {
                        // Nothing to be done here - we don't care if it closed or not.
                    }
                }
            }
        }

        // put unmodifiable list for all res type in the public resource map
        // this will simplify access
        for (ResourceType type : ResourceType.values()) {
            List<ResourceItem> list = mPublicResourceMap.get(type);
            if (list == null) {
                list = Collections.emptyList();
            } else {
                list = Collections.unmodifiableList(list);
            }

            // put the new list in the map
            mPublicResourceMap.put(type, list);
        }
    }
}

