/*
 * Copyright (C) 2020 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.internal.content.om;

import static com.android.internal.content.om.OverlayConfig.TAG;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.pm.PackagePartitions;
import android.content.pm.PackagePartitions.SystemPartition;
import android.os.FileUtils;
import android.util.ArraySet;
import android.util.Log;
import android.util.Xml;

import com.android.internal.content.om.OverlayScanner.ParsedOverlayInfo;
import com.android.internal.util.XmlUtils;

import libcore.io.IoUtils;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

/**
 * Responsible for parsing configurations of Runtime Resource Overlays that control mutability,
 * default enable state, and priority. To configure an overlay, create or modify the file located
 * at {@code partition}/overlay/config/config.xml where {@code partition} is the partition of the
 * overlay to be configured. In order to be configured, an overlay must reside in the overlay
 * directory of the partition in which the overlay is configured.
 *
 * @see #parseOverlay(File, XmlPullParser, OverlayScanner, ParsingContext)
 * @see #parseMerge(File, XmlPullParser, OverlayScanner, ParsingContext)
 **/
final class OverlayConfigParser {

    // Default values for overlay configurations.
    static final boolean DEFAULT_ENABLED_STATE = false;
    static final boolean DEFAULT_MUTABILITY = true;

    // Maximum recursive depth of processing merge tags.
    private static final int MAXIMUM_MERGE_DEPTH = 5;

    // The subdirectory within a partition's overlay directory that contains the configuration files
    // for the partition.
    private static final String CONFIG_DIRECTORY = "config";

    /**
     * The name of the configuration file to parse for overlay configurations. This class does not
     * scan for overlay configuration files within the {@link #CONFIG_DIRECTORY}; rather, other
     * files can be included at a particular position within this file using the <merge> tag.
     *
     * @see #parseMerge(File, XmlPullParser, OverlayScanner, ParsingContext)
     */
    private static final String CONFIG_DEFAULT_FILENAME = CONFIG_DIRECTORY + "/config.xml";

    /** Represents the configurations of a particular overlay. */
    public static class ParsedConfiguration {
        @NonNull
        public final String packageName;

        /** Whether or not the overlay is enabled by default. */
        public final boolean enabled;

        /**
         * Whether or not the overlay is mutable and can have its enabled state changed dynamically
         * using the {@code OverlayManagerService}.
         **/
        public final boolean mutable;

        /** The policy granted to overlays on the partition in which the overlay is located. */
        @NonNull
        public final String policy;

        /** Information extracted from the manifest of the overlay. */
        @NonNull
        public final ParsedOverlayInfo parsedInfo;

        ParsedConfiguration(@NonNull String packageName, boolean enabled, boolean mutable,
                @NonNull String policy, @NonNull ParsedOverlayInfo parsedInfo) {
            this.packageName = packageName;
            this.enabled = enabled;
            this.mutable = mutable;
            this.policy = policy;
            this.parsedInfo = parsedInfo;
        }

        @Override
        public String toString() {
            return getClass().getSimpleName() + String.format("{packageName=%s, enabled=%s"
                            + ", mutable=%s, policy=%s, parsedInfo=%s}", packageName, enabled,
                    mutable, policy, parsedInfo);
        }
    }

    static class OverlayPartition extends SystemPartition {
        // Policies passed to idmap2 during idmap creation.
        // Keep partition policy constants in sync with f/b/cmds/idmap2/include/idmap2/Policies.h.
        static final String POLICY_ODM = "odm";
        static final String POLICY_OEM = "oem";
        static final String POLICY_PRODUCT = "product";
        static final String POLICY_PUBLIC = "public";
        static final String POLICY_SYSTEM = "system";
        static final String POLICY_VENDOR = "vendor";

        @NonNull
        public final String policy;

        OverlayPartition(@NonNull SystemPartition partition) {
            super(partition);
            this.policy = policyForPartition(partition);
        }

        /**
         * Creates a partition containing the same folders as the original partition but with a
         * different root folder.
         */
        OverlayPartition(@NonNull File folder, @NonNull SystemPartition original) {
            super(folder, original);
            this.policy = policyForPartition(original);
        }

        private static String policyForPartition(SystemPartition partition) {
            switch (partition.type) {
                case PackagePartitions.PARTITION_SYSTEM:
                case PackagePartitions.PARTITION_SYSTEM_EXT:
                    return POLICY_SYSTEM;
                case PackagePartitions.PARTITION_VENDOR:
                    return POLICY_VENDOR;
                case PackagePartitions.PARTITION_ODM:
                    return POLICY_ODM;
                case PackagePartitions.PARTITION_OEM:
                    return POLICY_OEM;
                case PackagePartitions.PARTITION_PRODUCT:
                    return POLICY_PRODUCT;
                default:
                    throw new IllegalStateException("Unable to determine policy for "
                            + partition.getFolder());
            }
        }
    }

    /** This class holds state related to parsing the configurations of a partition. */
    private static class ParsingContext {
        // The overlay directory of the partition
        private final OverlayPartition mPartition;

        // The ordered list of configured overlays
        private final ArrayList<ParsedConfiguration> mOrderedConfigurations = new ArrayList<>();

        // The packages configured in the partition
        private final ArraySet<String> mConfiguredOverlays = new ArraySet<>();

        // Whether an mutable overlay has been configured in the partition
        private boolean mFoundMutableOverlay;

        // The current recursive depth of merging configuration files
        private int mMergeDepth;

        private ParsingContext(OverlayPartition partition) {
            mPartition = partition;
        }
    }

    /**
     * Retrieves overlays configured within the partition in increasing priority order.
     *
     * If {@code scanner} is null, then the {@link ParsedConfiguration#parsedInfo} fields of the
     * added configured overlays will be null and the parsing logic will not assert that the
     * configured overlays exist within the partition.
     *
     * @return list of configured overlays if configuration file exists; otherwise, null
     */
    @Nullable
    static ArrayList<ParsedConfiguration> getConfigurations(
            @NonNull OverlayPartition partition, @Nullable OverlayScanner scanner) {
        if (partition.getOverlayFolder() == null) {
            return null;
        }

        if (scanner != null) {
            scanner.scanDir(partition.getOverlayFolder());
        }

        final File configFile = new File(partition.getOverlayFolder(), CONFIG_DEFAULT_FILENAME);
        if (!configFile.exists()) {
            return null;
        }

        final ParsingContext parsingContext = new ParsingContext(partition);
        readConfigFile(configFile, scanner, parsingContext);
        return parsingContext.mOrderedConfigurations;
    }

    private static void readConfigFile(@NonNull File configFile, @Nullable OverlayScanner scanner,
            @NonNull ParsingContext parsingContext) {
        FileReader configReader;
        try {
            configReader = new FileReader(configFile);
        } catch (FileNotFoundException e) {
            Log.w(TAG, "Couldn't find or open overlay configuration file " + configFile);
            return;
        }

        try {
            final XmlPullParser parser = Xml.newPullParser();
            parser.setInput(configReader);
            XmlUtils.beginDocument(parser, "config");

            int depth = parser.getDepth();
            while (XmlUtils.nextElementWithin(parser, depth)) {
                final String name = parser.getName();
                switch (name) {
                    case "merge":
                        parseMerge(configFile, parser, scanner, parsingContext);
                        break;
                    case "overlay":
                        parseOverlay(configFile, parser, scanner, parsingContext);
                        break;
                    default:
                        Log.w(TAG, String.format("Tag %s is unknown in %s at %s",
                                name, configFile, parser.getPositionDescription()));
                        break;
                }
            }
        } catch (XmlPullParserException | IOException e) {
            Log.w(TAG, "Got exception parsing overlay configuration.", e);
        } finally {
            IoUtils.closeQuietly(configReader);
        }
    }

    /**
     * Parses a <merge> tag within an overlay configuration file.
     *
     * Merge tags allow for other configuration files to be "merged" at the current parsing
     * position into the current configuration file being parsed. The {@code path} attribute of the
     * tag represents the path of the file to merge relative to the directory containing overlay
     * configuration files.
     */
    private static void parseMerge(@NonNull File configFile, @NonNull XmlPullParser parser,
            @Nullable OverlayScanner scanner, @NonNull ParsingContext parsingContext) {
        final String path = parser.getAttributeValue(null, "path");
        if (path == null) {
            throw new IllegalStateException(String.format("<merge> without path in %s at %s"
                    + configFile, parser.getPositionDescription()));
        }

        if (path.startsWith("/")) {
            throw new IllegalStateException(String.format(
                    "Path %s must be relative to the directory containing overlay configurations "
                            + " files in %s at %s ", path, configFile,
                    parser.getPositionDescription()));
        }

        if (parsingContext.mMergeDepth++ == MAXIMUM_MERGE_DEPTH) {
            throw new IllegalStateException(String.format(
                    "Maximum <merge> depth exceeded in %s at %s", configFile,
                    parser.getPositionDescription()));
        }

        final File configDirectory;
        final File includedConfigFile;
        try {
            configDirectory = new File(parsingContext.mPartition.getOverlayFolder(),
                    CONFIG_DIRECTORY).getCanonicalFile();
            includedConfigFile = new File(configDirectory, path).getCanonicalFile();
        } catch (IOException e) {
            throw new IllegalStateException(
                    String.format("Couldn't find or open merged configuration file %s in %s at %s",
                            path, configFile, parser.getPositionDescription()), e);
        }

        if (!includedConfigFile.exists()) {
            throw new IllegalStateException(
                    String.format("Merged configuration file %s does not exist in %s at %s",
                            path, configFile, parser.getPositionDescription()));
        }

        if (!FileUtils.contains(configDirectory, includedConfigFile)) {
            throw new IllegalStateException(
                    String.format(
                            "Merged file %s outside of configuration directory in %s at %s",
                            includedConfigFile.getAbsolutePath(), includedConfigFile,
                            parser.getPositionDescription()));
        }

        readConfigFile(includedConfigFile, scanner, parsingContext);
        parsingContext.mMergeDepth--;
    }

    /**
     * Parses an <overlay> tag within an overlay configuration file.
     *
     * Requires a {@code package} attribute that indicates which package is being configured.
     * The optional {@code enabled} attribute controls whether or not the overlay is enabled by
     * default (default is false). The optional {@code mutable} attribute controls whether or
     * not the overlay is mutable and can have its enabled state changed at runtime (default is
     * true).
     *
     * The order in which overlays that override the same resources are configured matters. An
     * overlay will have a greater priority than overlays with configurations preceding its own
     * configuration.
     *
     * Configurations of immutable overlays must precede configurations of mutable overlays.
     * An overlay cannot be configured in multiple locations. All configured overlay must exist
     * within the partition of the configuration file. An overlay cannot be configured multiple
     * times in a single partition.
     *
     * Overlays not listed within a configuration file will be mutable and disabled by default. The
     * order of non-configured overlays when enabled by the OverlayManagerService is undefined.
     */
    private static void parseOverlay(@NonNull File configFile, @NonNull XmlPullParser parser,
            @Nullable OverlayScanner scanner, @NonNull ParsingContext parsingContext) {
        final String packageName = parser.getAttributeValue(null, "package");
        if (packageName == null) {
            throw new IllegalStateException(String.format("\"<overlay> without package in %s at %s",
                    configFile, parser.getPositionDescription()));
        }

        // Ensure the overlay being configured is present in the partition during zygote
        // initialization.
        ParsedOverlayInfo info = null;
        if (scanner != null) {
            info = scanner.getParsedInfo(packageName);
            if (info == null|| !parsingContext.mPartition.containsOverlay(info.path)) {
                throw new IllegalStateException(
                        String.format("overlay %s not present in partition %s in %s at %s",
                                packageName, parsingContext.mPartition.getOverlayFolder(),
                                configFile, parser.getPositionDescription()));
            }
        }

        if (parsingContext.mConfiguredOverlays.contains(packageName)) {
            throw new IllegalStateException(
                    String.format("overlay %s configured multiple times in a single partition"
                                    + " in %s at %s", packageName, configFile,
                            parser.getPositionDescription()));
        }

        boolean isEnabled = DEFAULT_ENABLED_STATE;
        final String enabled = parser.getAttributeValue(null, "enabled");
        if (enabled != null) {
            isEnabled = !"false".equals(enabled);
        }

        boolean isMutable = DEFAULT_MUTABILITY;
        final String mutable = parser.getAttributeValue(null, "mutable");
        if (mutable != null) {
            isMutable = !"false".equals(mutable);
            if (!isMutable && parsingContext.mFoundMutableOverlay) {
                throw new IllegalStateException(String.format(
                        "immutable overlays must precede mutable overlays:"
                                + " found in %s at %s",
                        configFile, parser.getPositionDescription()));
            }
        }

        if (isMutable) {
            parsingContext.mFoundMutableOverlay = true;
        } else if (!isEnabled) {
            // Default disabled, immutable overlays may be a misconfiguration of the system so warn
            // developers.
            Log.w(TAG, "found default-disabled immutable overlay " + packageName);
        }

        final ParsedConfiguration Config = new ParsedConfiguration(packageName, isEnabled,
                isMutable, parsingContext.mPartition.policy, info);
        parsingContext.mConfiguredOverlays.add(packageName);
        parsingContext.mOrderedConfigurations.add(Config);
    }
}
