/*
 * Copyright (C) 2015 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.tv.parental;

import android.content.ContentUris;
import android.content.Context;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.media.tv.TvContentRatingSystemInfo;
import android.net.Uri;
import android.util.Log;
import com.android.tv.parental.ContentRatingSystem.Order;
import com.android.tv.parental.ContentRatingSystem.Rating;
import com.android.tv.parental.ContentRatingSystem.SubRating;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

/** Parses Content Ratings */
public class ContentRatingsParser {
    private static final String TAG = "ContentRatingsParser";
    private static final boolean DEBUG = false;

    public static final String DOMAIN_SYSTEM_RATINGS = "com.android.tv";

    private static final String TAG_RATING_SYSTEM_DEFINITIONS = "rating-system-definitions";
    private static final String TAG_RATING_SYSTEM_DEFINITION = "rating-system-definition";
    private static final String TAG_SUB_RATING_DEFINITION = "sub-rating-definition";
    private static final String TAG_RATING_DEFINITION = "rating-definition";
    private static final String TAG_SUB_RATING = "sub-rating";
    private static final String TAG_RATING = "rating";
    private static final String TAG_RATING_ORDER = "rating-order";

    private static final String ATTR_VERSION_CODE = "versionCode";
    private static final String ATTR_NAME = "name";
    private static final String ATTR_TITLE = "title";
    private static final String ATTR_COUNTRY = "country";
    private static final String ATTR_ICON = "icon";
    private static final String ATTR_DESCRIPTION = "description";
    private static final String ATTR_CONTENT_AGE_HINT = "contentAgeHint";
    private static final String VERSION_CODE = "1";

    private final Context mContext;
    private Resources mResources;
    private String mXmlVersionCode;

    public ContentRatingsParser(Context context) {
        mContext = context;
    }

    public List<ContentRatingSystem> parse(TvContentRatingSystemInfo info) {
        List<ContentRatingSystem> ratingSystems = null;
        Uri uri = info.getXmlUri();
        if (DEBUG) Log.d(TAG, "Parsing rating system for " + uri);
        try {
            String packageName = uri.getAuthority();
            int resId = (int) ContentUris.parseId(uri);
            try (XmlResourceParser parser =
                    mContext.getPackageManager().getXml(packageName, resId, null)) {
                if (parser == null) {
                    throw new IllegalArgumentException("Cannot get XML with URI " + uri);
                }
                ratingSystems = parse(parser, packageName, !info.isSystemDefined());
            }
        } catch (Exception e) {
            // Catching all exceptions and print which URI is malformed XML with description
            // and stack trace here.
            // TODO: We may want to print message to stdout.
            Log.w(TAG, "Error parsing XML " + uri, e);
        }
        return ratingSystems;
    }

    private List<ContentRatingSystem> parse(
            XmlResourceParser parser, String domain, boolean isCustom)
            throws XmlPullParserException, IOException {
        try {
            mResources = mContext.getPackageManager().getResourcesForApplication(domain);
        } catch (NameNotFoundException e) {
            Log.w(TAG, "Failed to get resources for " + domain, e);
            mResources = mContext.getResources();
        }
        // TODO: find another way to replace the domain the content rating systems defined in TV.
        // Live TV app provides public content rating systems. Therefore, the domain of
        // the content rating systems defined in TV app should be com.android.tv instead of
        // this app's package name.
        if (domain.equals(mContext.getPackageName())) {
            domain = DOMAIN_SYSTEM_RATINGS;
        }

        // Consume all START_DOCUMENT which can appear more than once.
        while (parser.next() == XmlPullParser.START_DOCUMENT) {}

        int eventType = parser.getEventType();
        assertEquals(eventType, XmlPullParser.START_TAG, "Malformed XML: Not a valid XML file");
        assertEquals(
                parser.getName(),
                TAG_RATING_SYSTEM_DEFINITIONS,
                "Malformed XML: Should start with tag " + TAG_RATING_SYSTEM_DEFINITIONS);

        boolean hasVersionAttr = false;
        for (int i = 0; i < parser.getAttributeCount(); i++) {
            String attr = parser.getAttributeName(i);
            if (ATTR_VERSION_CODE.equals(attr)) {
                hasVersionAttr = true;
                mXmlVersionCode = parser.getAttributeValue(i);
            }
        }
        if (!hasVersionAttr) {
            throw new XmlPullParserException(
                    "Malformed XML: Should contains a version attribute"
                            + " in "
                            + TAG_RATING_SYSTEM_DEFINITIONS);
        }

        List<ContentRatingSystem> ratingSystems = new ArrayList<>();
        while (parser.next() != XmlPullParser.END_DOCUMENT) {
            switch (parser.getEventType()) {
                case XmlPullParser.START_TAG:
                    if (TAG_RATING_SYSTEM_DEFINITION.equals(parser.getName())) {
                        ratingSystems.add(parseRatingSystemDefinition(parser, domain, isCustom));
                    } else {
                        checkVersion(
                                "Malformed XML: Should contains " + TAG_RATING_SYSTEM_DEFINITION);
                    }
                    break;
                case XmlPullParser.END_TAG:
                    if (TAG_RATING_SYSTEM_DEFINITIONS.equals(parser.getName())) {
                        eventType = parser.next();
                        assertEquals(
                                eventType,
                                XmlPullParser.END_DOCUMENT,
                                "Malformed XML: Should end with tag "
                                        + TAG_RATING_SYSTEM_DEFINITIONS);
                        return ratingSystems;
                    } else {
                        checkVersion(
                                "Malformed XML: Should end with tag "
                                        + TAG_RATING_SYSTEM_DEFINITIONS);
                    }
            }
        }
        throw new XmlPullParserException(
                TAG_RATING_SYSTEM_DEFINITIONS
                        + " section is incomplete or section ending tag is missing");
    }

    private static void assertEquals(int a, int b, String msg) throws XmlPullParserException {
        if (a != b) {
            throw new XmlPullParserException(msg);
        }
    }

    private static void assertEquals(String a, String b, String msg) throws XmlPullParserException {
        if (!b.equals(a)) {
            throw new XmlPullParserException(msg);
        }
    }

    private void checkVersion(String msg) throws XmlPullParserException {
        if (!VERSION_CODE.equals(mXmlVersionCode)) {
            throw new XmlPullParserException(msg);
        }
    }

    private ContentRatingSystem parseRatingSystemDefinition(
            XmlResourceParser parser, String domain, boolean isCustom)
            throws XmlPullParserException, IOException {
        ContentRatingSystem.Builder builder = new ContentRatingSystem.Builder(mContext);

        builder.setDomain(domain);
        for (int i = 0; i < parser.getAttributeCount(); i++) {
            String attr = parser.getAttributeName(i);
            switch (attr) {
                case ATTR_NAME:
                    builder.setName(parser.getAttributeValue(i));
                    break;
                case ATTR_COUNTRY:
                    for (String country : parser.getAttributeValue(i).split("\\s*,\\s*")) {
                        builder.addCountry(country);
                    }
                    break;
                case ATTR_TITLE:
                    builder.setTitle(getTitle(parser, i));
                    break;
                case ATTR_DESCRIPTION:
                    builder.setDescription(
                            mResources.getString(parser.getAttributeResourceValue(i, 0)));
                    break;
                default:
                    checkVersion(
                            "Malformed XML: Unknown attribute "
                                    + attr
                                    + " in "
                                    + TAG_RATING_SYSTEM_DEFINITION);
            }
        }

        while (parser.next() != XmlPullParser.END_DOCUMENT) {
            int eventType = parser.getEventType();
            switch (eventType) {
                case XmlPullParser.START_TAG:
                    String tag = parser.getName();
                    switch (tag) {
                        case TAG_RATING_DEFINITION:
                            builder.addRatingBuilder(parseRatingDefinition(parser));
                            break;
                        case TAG_SUB_RATING_DEFINITION:
                            builder.addSubRatingBuilder(parseSubRatingDefinition(parser));
                            break;
                        case TAG_RATING_ORDER:
                            builder.addOrderBuilder(parseOrder(parser));
                            break;
                        default:
                            checkVersion(
                                    "Malformed XML: Unknown tag "
                                            + tag
                                            + " in "
                                            + TAG_RATING_SYSTEM_DEFINITION);
                    }
                    break;
                case XmlPullParser.END_TAG:
                    if (TAG_RATING_SYSTEM_DEFINITION.equals(parser.getName())) {
                        builder.setIsCustom(isCustom);
                        return builder.build();
                    } else {
                        checkVersion(
                                "Malformed XML: Tag mismatch for " + TAG_RATING_SYSTEM_DEFINITION);
                    }
                    break;
                default:
                    checkVersion(
                            "Malformed XML: Unknown event type "
                                    + eventType
                                    + " in "
                                    + TAG_RATING_SYSTEM_DEFINITION);
            }
        }
        throw new XmlPullParserException(
                TAG_RATING_SYSTEM_DEFINITION
                        + " section is incomplete or section ending tag is missing");
    }

    private Rating.Builder parseRatingDefinition(XmlResourceParser parser)
            throws XmlPullParserException, IOException {
        Rating.Builder builder = new Rating.Builder();

        for (int i = 0; i < parser.getAttributeCount(); i++) {
            String attr = parser.getAttributeName(i);
            switch (attr) {
                case ATTR_NAME:
                    builder.setName(parser.getAttributeValue(i));
                    break;
                case ATTR_TITLE:
                    builder.setTitle(getTitle(parser, i));
                    break;
                case ATTR_DESCRIPTION:
                    builder.setDescription(
                            mResources.getString(parser.getAttributeResourceValue(i, 0)));
                    break;
                case ATTR_ICON:
                    builder.setIcon(
                            mResources.getDrawable(parser.getAttributeResourceValue(i, 0), null));
                    break;
                case ATTR_CONTENT_AGE_HINT:
                    int contentAgeHint = -1;
                    try {
                        contentAgeHint = Integer.parseInt(parser.getAttributeValue(i));
                    } catch (NumberFormatException ignored) {
                    }

                    if (contentAgeHint < 0) {
                        throw new XmlPullParserException(
                                "Malformed XML: "
                                        + ATTR_CONTENT_AGE_HINT
                                        + " should be a non-negative number");
                    }
                    builder.setContentAgeHint(contentAgeHint);
                    break;
                default:
                    checkVersion(
                            "Malformed XML: Unknown attribute "
                                    + attr
                                    + " in "
                                    + TAG_RATING_DEFINITION);
            }
        }

        while (parser.next() != XmlPullParser.END_DOCUMENT) {
            switch (parser.getEventType()) {
                case XmlPullParser.START_TAG:
                    if (TAG_SUB_RATING.equals(parser.getName())) {
                        builder = parseSubRating(parser, builder);
                    } else {
                        checkVersion(
                                ("Malformed XML: Only "
                                        + TAG_SUB_RATING
                                        + " is allowed in "
                                        + TAG_RATING_DEFINITION));
                    }
                    break;
                case XmlPullParser.END_TAG:
                    if (TAG_RATING_DEFINITION.equals(parser.getName())) {
                        return builder;
                    } else {
                        checkVersion("Malformed XML: Tag mismatch for " + TAG_RATING_DEFINITION);
                    }
            }
        }
        throw new XmlPullParserException(
                TAG_RATING_DEFINITION + " section is incomplete or section ending tag is missing");
    }

    private SubRating.Builder parseSubRatingDefinition(XmlResourceParser parser)
            throws XmlPullParserException, IOException {
        SubRating.Builder builder = new SubRating.Builder();

        for (int i = 0; i < parser.getAttributeCount(); i++) {
            String attr = parser.getAttributeName(i);
            switch (attr) {
                case ATTR_NAME:
                    builder.setName(parser.getAttributeValue(i));
                    break;
                case ATTR_TITLE:
                    builder.setTitle(getTitle(parser, i));
                    break;
                case ATTR_DESCRIPTION:
                    builder.setDescription(
                            mResources.getString(parser.getAttributeResourceValue(i, 0)));
                    break;
                case ATTR_ICON:
                    builder.setIcon(
                            mResources.getDrawable(parser.getAttributeResourceValue(i, 0), null));
                    break;
                default:
                    checkVersion(
                            "Malformed XML: Unknown attribute "
                                    + attr
                                    + " in "
                                    + TAG_SUB_RATING_DEFINITION);
            }
        }

        while (parser.next() != XmlPullParser.END_DOCUMENT) {
            switch (parser.getEventType()) {
                case XmlPullParser.END_TAG:
                    if (TAG_SUB_RATING_DEFINITION.equals(parser.getName())) {
                        return builder;
                    } else {
                        checkVersion(
                                "Malformed XML: " + TAG_SUB_RATING_DEFINITION + " isn't closed");
                    }
                    break;
                default:
                    checkVersion("Malformed XML: " + TAG_SUB_RATING_DEFINITION + " has child");
            }
        }
        throw new XmlPullParserException(
                TAG_SUB_RATING_DEFINITION
                        + " section is incomplete or section ending tag is missing");
    }

    private Order.Builder parseOrder(XmlResourceParser parser)
            throws XmlPullParserException, IOException {
        Order.Builder builder = new Order.Builder();

        assertEquals(
                parser.getAttributeCount(),
                0,
                "Malformed XML: Attribute isn't allowed in " + TAG_RATING_ORDER);

        while (parser.next() != XmlPullParser.END_DOCUMENT) {
            switch (parser.getEventType()) {
                case XmlPullParser.START_TAG:
                    if (TAG_RATING.equals(parser.getName())) {
                        builder = parseRating(parser, builder);
                    } else {
                        checkVersion(
                                "Malformed XML: Only "
                                        + TAG_RATING
                                        + " is allowed in "
                                        + TAG_RATING_ORDER);
                    }
                    break;
                case XmlPullParser.END_TAG:
                    assertEquals(
                            parser.getName(),
                            TAG_RATING_ORDER,
                            "Malformed XML: Tag mismatch for " + TAG_RATING_ORDER);
                    return builder;
            }
        }
        throw new XmlPullParserException(
                TAG_RATING_ORDER + " section is incomplete or section ending tag is missing");
    }

    private Order.Builder parseRating(XmlResourceParser parser, Order.Builder builder)
            throws XmlPullParserException, IOException {
        for (int i = 0; i < parser.getAttributeCount(); i++) {
            String attr = parser.getAttributeName(i);
            switch (attr) {
                case ATTR_NAME:
                    builder.addRatingName(parser.getAttributeValue(i));
                    break;
                default:
                    checkVersion(
                            "Malformed XML: "
                                    + TAG_RATING_ORDER
                                    + " should only contain "
                                    + ATTR_NAME);
            }
        }

        while (parser.next() != XmlPullParser.END_DOCUMENT) {
            if (parser.getEventType() == XmlPullParser.END_TAG) {
                if (TAG_RATING.equals(parser.getName())) {
                    return builder;
                } else {
                    checkVersion("Malformed XML: " + TAG_RATING + " has child");
                }
            }
        }
        throw new XmlPullParserException(
                TAG_RATING + " section is incomplete or section ending tag is missing");
    }

    private Rating.Builder parseSubRating(XmlResourceParser parser, Rating.Builder builder)
            throws XmlPullParserException, IOException {
        for (int i = 0; i < parser.getAttributeCount(); i++) {
            String attr = parser.getAttributeName(i);
            switch (attr) {
                case ATTR_NAME:
                    builder.addSubRatingName(parser.getAttributeValue(i));
                    break;
                default:
                    checkVersion(
                            "Malformed XML: "
                                    + TAG_SUB_RATING
                                    + " should only contain "
                                    + ATTR_NAME);
            }
        }

        while (parser.next() != XmlPullParser.END_DOCUMENT) {
            if (parser.getEventType() == XmlPullParser.END_TAG) {
                if (TAG_SUB_RATING.equals(parser.getName())) {
                    return builder;
                } else {
                    checkVersion("Malformed XML: " + TAG_SUB_RATING + " has child");
                }
            }
        }
        throw new XmlPullParserException(
                TAG_SUB_RATING + " section is incomplete or section ending tag is missing");
    }

    // Title might be a resource id or a string value. Try loading as an id first, then use the
    // string if that fails.
    private String getTitle(XmlResourceParser parser, int index) {
        int titleResId = parser.getAttributeResourceValue(index, 0);
        if (titleResId != 0) {
            return mResources.getString(titleResId);
        }
        return parser.getAttributeValue(index);
    }
}
