/*
 * Copyright (C) 2008 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 android.util;

import com.android.ide.common.rendering.api.AttrResourceValue;
import com.android.ide.common.rendering.api.ResourceNamespace;
import com.android.ide.common.rendering.api.ResourceReference;
import com.android.ide.common.rendering.api.ResourceValue;
import com.android.internal.util.XmlUtils;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.BridgeConstants;
import com.android.layoutlib.bridge.android.BridgeContext;
import com.android.layoutlib.bridge.android.UnresolvedResourceValue;
import com.android.layoutlib.bridge.android.XmlPullParserResolver;
import com.android.layoutlib.bridge.impl.ResourceHelper;
import com.android.resources.ResourceType;

import org.xmlpull.v1.XmlPullParser;

import android.annotation.NonNull;
import android.annotation.Nullable;

import java.util.Map;
import java.util.function.Function;

/**
 * A correct implementation of the {@link AttributeSet} interface on top of a XmlPullParser
 */
public class BridgeXmlPullAttributes extends XmlPullAttributes implements ResolvingAttributeSet {

    interface EnumValueSupplier {
        @Nullable
        Map<String, Integer> getEnumValues(
                @NonNull ResourceNamespace namespace, @NonNull String attrName);
    }

    private final BridgeContext mContext;
    private final ResourceNamespace mXmlFileResourceNamespace;
    private final ResourceNamespace.Resolver mResourceNamespaceResolver;
    private final Function<String, Map<String, Integer>> mFrameworkEnumValueSupplier;
    private final EnumValueSupplier mProjectEnumValueSupplier;

    // VisibleForTesting
    BridgeXmlPullAttributes(
            @NonNull XmlPullParser parser,
            @NonNull BridgeContext context,
            @NonNull ResourceNamespace xmlFileResourceNamespace,
            @NonNull Function<String, Map<String, Integer>> frameworkEnumValueSupplier,
            @NonNull EnumValueSupplier projectEnumValueSupplier) {
        super(parser);
        mContext = context;
        mFrameworkEnumValueSupplier = frameworkEnumValueSupplier;
        mProjectEnumValueSupplier = projectEnumValueSupplier;
        mXmlFileResourceNamespace = xmlFileResourceNamespace;
        mResourceNamespaceResolver =
                new XmlPullParserResolver(
                        mParser, context.getLayoutlibCallback().getImplicitNamespaces());
    }

    public BridgeXmlPullAttributes(
            @NonNull XmlPullParser parser,
            @NonNull BridgeContext context,
            @NonNull ResourceNamespace xmlFileResourceNamespace) {
        this(parser, context, xmlFileResourceNamespace, Bridge::getEnumValues, (ns, attrName) -> {
            ResourceValue attr =
                    context.getRenderResources().getUnresolvedResource(
                            ResourceReference.attr(ns, attrName));
            return attr instanceof AttrResourceValue
                    ? ((AttrResourceValue) attr).getAttributeValues()
                    : null;
        });
    }

    /*
     * (non-Javadoc)
     * @see android.util.XmlPullAttributes#getAttributeNameResource(int)
     *
     * This methods must return com.android.internal.R.attr.<name> matching
     * the name of the attribute.
     * It returns 0 if it doesn't find anything.
     */
    @Override
    public int getAttributeNameResource(int index) {
        // get the attribute name.
        String name = getAttributeName(index);

        // get the attribute namespace
        String ns = mParser.getAttributeNamespace(index);

        if (BridgeConstants.NS_RESOURCES.equals(ns)) {
            return Bridge.getResourceId(ResourceType.ATTR, name);
        }

        // this is not an attribute in the android namespace, we query the customviewloader, if
        // the namespaces match.
        if (mContext.getLayoutlibCallback().getNamespace().equals(ns)) {
            // TODO(namespaces): cache the namespace objects.
            ResourceNamespace namespace = ResourceNamespace.fromNamespaceUri(ns);
            if (namespace != null) {
                return mContext.getLayoutlibCallback().getOrGenerateResourceId(
                        ResourceReference.attr(namespace, name));
            }
        }

        return 0;
    }

    @Override
    public int getAttributeListValue(String namespace, String attribute,
            String[] options, int defaultValue) {
        String value = getAttributeValue(namespace, attribute);
        if (value != null) {
            ResourceValue r = getResourceValue(value);

            if (r != null) {
                value = r.getValue();
            }

            return XmlUtils.convertValueToList(value, options, defaultValue);
        }

        return defaultValue;
    }

    @Override
    public boolean getAttributeBooleanValue(String namespace, String attribute,
            boolean defaultValue) {
        String value = getAttributeValue(namespace, attribute);
        if (value != null) {
            ResourceValue r = getResourceValue(value);

            if (r != null) {
                value = r.getValue();
            }

            return XmlUtils.convertValueToBoolean(value, defaultValue);
        }

        return defaultValue;
    }

    @Override
    public int getAttributeResourceValue(String namespace, String attribute, int defaultValue) {
        String value = getAttributeValue(namespace, attribute);

        return resolveResourceValue(value, defaultValue);
    }

    @Override
    public int getAttributeIntValue(String namespace, String attribute, int defaultValue) {
        String value = getAttributeValue(namespace, attribute);
        if (value == null) {
            return defaultValue;
        }

        ResourceValue r = getResourceValue(value);

        if (r != null) {
            value = r.getValue();
        }

        if (value.charAt(0) == '#') {
            return ResourceHelper.getColor(value);
        }

        try {
            return XmlUtils.convertValueToInt(value, defaultValue);
        } catch (NumberFormatException e) {
            // This is probably an enum
            Map<String, Integer> enumValues = null;
            if (BridgeConstants.NS_RESOURCES.equals(namespace)) {
                enumValues = mFrameworkEnumValueSupplier.apply(attribute);
            } else {
                ResourceNamespace attrNamespace = ResourceNamespace.fromNamespaceUri(namespace);
                if (attrNamespace != null) {
                    enumValues = mProjectEnumValueSupplier.getEnumValues(attrNamespace, attribute);
                }
            }

            Integer enumValue = enumValues != null ? enumValues.get(value) : null;
            if (enumValue != null) {
                return enumValue;
            }

            // We weren't able to find the enum int value
            throw e;
        }
    }

    @Override
    public int getAttributeUnsignedIntValue(String namespace, String attribute,
            int defaultValue) {
        String value = getAttributeValue(namespace, attribute);
        if (value != null) {
            ResourceValue r = getResourceValue(value);

            if (r != null) {
                value = r.getValue();
            }

            return XmlUtils.convertValueToUnsignedInt(value, defaultValue);
        }

        return defaultValue;
    }

    @Override
    public float getAttributeFloatValue(String namespace, String attribute,
            float defaultValue) {
        String s = getAttributeValue(namespace, attribute);
        if (s != null) {
            ResourceValue r = getResourceValue(s);

            if (r != null) {
                s = r.getValue();
            }

            return Float.parseFloat(s);
        }

        return defaultValue;
    }

    @Override
    public int getAttributeListValue(int index,
            String[] options, int defaultValue) {
        return XmlUtils.convertValueToList(
            getAttributeValue(index), options, defaultValue);
    }

    @Override
    public boolean getAttributeBooleanValue(int index, boolean defaultValue) {
        String value = getAttributeValue(index);
        if (value != null) {
            ResourceValue r = getResourceValue(value);

            if (r != null) {
                value = r.getValue();
            }

            return XmlUtils.convertValueToBoolean(value, defaultValue);
        }

        return defaultValue;
    }

    @Override
    public int getAttributeResourceValue(int index, int defaultValue) {
        String value = getAttributeValue(index);

        return resolveResourceValue(value, defaultValue);
    }

    @Override
    public int getAttributeIntValue(int index, int defaultValue) {
        return getAttributeIntValue(
                mParser.getAttributeNamespace(index), getAttributeName(index), defaultValue);
    }

    @Override
    public int getAttributeUnsignedIntValue(int index, int defaultValue) {
        String value = getAttributeValue(index);
        if (value != null) {
            ResourceValue r = getResourceValue(value);

            if (r != null) {
                value = r.getValue();
            }

            return XmlUtils.convertValueToUnsignedInt(value, defaultValue);
        }

        return defaultValue;
    }

    @Override
    public float getAttributeFloatValue(int index, float defaultValue) {
        String s = getAttributeValue(index);
        if (s != null) {
            ResourceValue r = getResourceValue(s);

            if (r != null) {
                s = r.getValue();
            }

            return Float.parseFloat(s);
        }

        return defaultValue;
    }

    @Override
    @Nullable
    public ResourceValue getResolvedAttributeValue(@Nullable String namespace,
            @NonNull String name) {
        String s = getAttributeValue(namespace, name);
        return s == null ? null : getResourceValue(s);
    }

    // -- private helper methods

    /**
     * Returns a resolved {@link ResourceValue} from a given value.
     */
    private ResourceValue getResourceValue(String value) {
        // now look for this particular value
        return mContext.getRenderResources().resolveResValue(
                new UnresolvedResourceValue(
                        value, mXmlFileResourceNamespace, mResourceNamespaceResolver));
    }

    /**
     * Resolves and return a value to its associated integer.
     */
    private int resolveResourceValue(String value, int defaultValue) {
        ResourceValue resource = getResourceValue(value);
        if (resource != null) {
            return resource.isFramework() ?
                    Bridge.getResourceId(resource.getResourceType(), resource.getName()) :
                    mContext.getLayoutlibCallback().getOrGenerateResourceId(resource.asReference());
        }

        return defaultValue;
    }
}
