/*
 * Copyright (C) 2012 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.manifmerger;

import com.android.common.annotations.NonNull;
import com.android.common.annotations.Nullable;


/**
 * Logger interface for the {@link com.android.manifmerger.ManifestMerger}.
 */
public interface IMergerLog {

    /** Severity of the error message. */
    public enum Severity {
        /**
         * A very low severity information. This does not stop processing.
         * Clients might want to have a "not verbose" flag to not display this.
         */
        INFO,
        /**
         * A warning. This does not stop processing.
         * */
        WARNING,
        /**
         * A fatal error.
         * The merger does not stop on errors, in an attempt to accumulate as much
         * info as possible to return to the user. However in case even one error
         * is generated the output should not be used, if any.
         */
        ERROR
    }

    /**
     * Logs an error that occurred at a specific single manifest.
     *
     * @param severity Whether this is an actual error or a mere warning.
     * @param location A file and line location of where the error was detected.
     * @param message A message string, suitable for {@link String#format(String, Object...)}.
     * @param msgParams The optional parameters for the {@code message} string.
     */
    public abstract void error(
        @NonNull Severity severity,
        @NonNull FileAndLine location,
        @NonNull String message,
        Object... msgParams);

    /**
     * Logs a conflict, that is an error that happens when comparing 2 manifests.
     *
     * @param severity Whether this is an actual error or a mere warning.
     * @param location1 A file and line location of where the error was detected.
     *  By convention, location1 is generally the main manifest location.
     * @param location2 A file and line location of where the error was detected.
     *  By convention, location2 is generally a library location.
     * @param message A message string, suitable for {@link String#format(String, Object...)}.
     * @param msgParams The optional parameters for the {@code message} string.
     */
    public abstract void conflict(
        @NonNull Severity severity,
        @NonNull FileAndLine location1,
        @NonNull FileAndLine location2,
        @NonNull String message,
        Object... msgParams);

    /**
     * Information about the file and line number where an error ocurred.
     */
    public static class FileAndLine {
        private final String mFilePath;
        private final int mLine;

        /**
         * Constructs a new {@link com.android.manifmerger.IMergerLog.FileAndLine}.
         *
         * @param filePath The file path. This is typically a file path when the
         *   merge is initiated via the {@code process(File...)} interface.
         *   When using the {@code process(Document...)} interface, this will be
         *   one of the magic constants {@link com.android.manifmerger.IMergerLog#LIBRARY} or
         *   {@link com.android.manifmerger.IMergerLog#MAIN_MANIFEST}. When that fails, null is used.
         * @param line The line number where the error occurred in the XML file.
         *   Zero is used when the line number isn't known (e.g. when the error
         *   happens at the document level rather than on a specific element.)
         */
        public FileAndLine(@Nullable String filePath, int line) {
            mFilePath = filePath;
            mLine = line;
        }

        /**
         * Returns the file path.
         * <p/>
         * This is typically a file path when the merge is initiated via the
         * {@code process(File...)} interface.
         * When using the {@code process(Document...)} interface, this will be
         * one of the magic constants {@link com.android.manifmerger.IMergerLog#LIBRARY} or
         * {@link com.android.manifmerger.IMergerLog#MAIN_MANIFEST}.
         * When that fails, null is used.
         */
        public @Nullable String getFileName() {
            return mFilePath;
        }

        /**
         * Returns the line number where the error occurred in the XML file.
         * Zero is used when the line number isn't known (e.g. when the error
         * happens at the document level rather than on a specific element.)
         */
        public int getLine() {
            return mLine;
        }

        /**
         * Displays the information in the form "file:line".
         */
        @Override
        public String toString() {
            String name = mFilePath;
            if (MAIN_MANIFEST.equals(name)) {
                name = "main manifest";         // translatable
            } else if (LIBRARY.equals(name)) {
                name = "library";               // translatable
            } else if (name == null) {
                name = "(Unknown)";             // translatable
            }
            if (mLine <= 0) {
                return name;
            } else {
                return name + ':' + mLine;
            }
        }
    }

    /**
     * The reference to the "main manifest" used in {@link com.android.manifmerger.IMergerLog.FileAndLine} when the
     * path to the main manifest file isn't known. This happens when the
     * {@link com.android.manifmerger.ManifestMerger} is called with the {@code process(Document...)}
     * interface.
     */
    public static final String MAIN_MANIFEST = "@main";     //$NON-NLS-1$

    /**
     * The reference to "a library" used in {@link com.android.manifmerger.IMergerLog.FileAndLine} when the
     * path to the library file isn't known. This happens when the
     * {@link com.android.manifmerger.ManifestMerger} is called with the {@code process(Document...)}
     * interface.
     */
    public static final String LIBRARY = "@library";        //$NON-NLS-1$

}
