/*
 * Copyright 2010 Google Inc.
 *
 * 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.accessibility;

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

/**
 * An object that fetches all Android layout files and manages the testing of
 * the files with the use of the AccessibilityValidationContentHandler. This
 * object also reports on any errors encountered during the testing.
 *
 * @author dtseng@google.com (David Tseng)
 */
public class AccessibilityValidator {
    /** The root path to scan for Android layout files. */
    private final File mRootFilePath;
    /** Errors generated by thrown exceptions (and not by validation errors). */
    private final List<String> mGeneralErrors = new ArrayList<String>();
    /** A list of files we wish to have tested. */
    private List<InputSource> mLayoutFiles;
    /** The total number of validation test errors across all files. */
    private int mTotalValidationErrors = 0;
    /** The path to the Android sdk jar. */
    private final File mAndroidSdkPath;

    /** The object that handles our logging. */
    private static final Logger sLogger = Logger.getLogger("android.accessibility");

    /**
     * The entry point to this tool.
     * 
     * @param <args>
     *            path on which to search for layout xml files that need
     *            validation
     */
    public static void main(String[] args) {
        sLogger.info("AccessibilityValidator");
        if (args.length == 2) {
            sLogger.info("Validating classes using android jar for subclasses of ImageView");
            new AccessibilityValidator(args[0], args[1]).run();
        } else {
            sLogger.info("Usage: java AccessibilityValidator <path> <Android jar path>");
            return;
        }
    }

    /**
     * Constructs an AccessibilityValidator object using the root path and the
     * android jar path.
     */
    public AccessibilityValidator(String rootPath, String androidSdkPath) {
        mRootFilePath = new File(rootPath);
        mAndroidSdkPath = new File(androidSdkPath);

        if (!mRootFilePath.exists()) {
            throw new IllegalArgumentException("Invalid root path specified "
                    + rootPath);
        } else if (!mAndroidSdkPath.exists()) {
            throw new IllegalArgumentException(
                    "Invalid android sdk path specified " + androidSdkPath);
        }
    }

    /**
     * Performs validation of Android layout files and logs errors that have
     * been encountered during the validation. Returns true if the validation
     * passes.
     */
    private boolean run() {
        sLogger.info("Validating files under " + mRootFilePath);
        mLayoutFiles = findLayoutFiles(mRootFilePath);
        validateFiles();
        for (String error : mGeneralErrors) {
            sLogger.info(error);
        }
        sLogger.info("done with validation");
        return mGeneralErrors.size() == 0;
    }

    /**
     * Accumulates a list of files under the path that meet two constraints.
     * Firstly, it has a containing (parent) directory of "layout". Secondly, it
     * has an xml extension
     */
    private List<InputSource> findLayoutFiles(File directory) {
        List<InputSource> layoutFiles = new ArrayList<InputSource>();

        for (File file : directory.listFiles()) {
            // The file is a directory; recurse on the file.
            if (file.isDirectory()) {
                List<InputSource> directoryFiles = findLayoutFiles(file);
                layoutFiles.addAll(directoryFiles);
                // Does the containing directory and filename meet our
                // constraints?
            } else if (directory.getName().toLowerCase().contains("layout")
                    && file.getName().toLowerCase().endsWith(".xml")) {
                InputSource addition;
                try {
                    addition = new InputSource(new FileReader(file));
                    // Store this explicitly for logging.
                    addition.setPublicId(file.toString());
                    layoutFiles.add(addition);
                } catch (FileNotFoundException fileNotFoundException) {
                    mGeneralErrors.add("File not found "
                            + fileNotFoundException);
                }
            }
        }

        return layoutFiles;
    }

    /*
     * Processes a list of files via an AccessibilityValidationContentHandler.
     * The caller will only be notified of errors via logging.
     */
    public void validateFiles() {
        sLogger.info("Validating " + getLayoutFiles().size());
        XMLReader reader;
        try {
            reader = XMLReaderFactory.createXMLReader();
        } catch (SAXException saxExp) {
            mGeneralErrors.add("Error " + saxExp);
            return;
        }
        for (InputSource file : getLayoutFiles()) {
            try {
                AccessibilityValidationContentHandler contentHandler
                = new AccessibilityValidationContentHandler(
                        file.getPublicId(), mAndroidSdkPath);
                reader.setContentHandler(contentHandler);
                reader.parse(file);
                mTotalValidationErrors += contentHandler.getValidationErrors();
            } catch (IOException ioExp) {
                mGeneralErrors.add("Error reading file " + ioExp);
            } catch (SAXException saxExp) {
                mGeneralErrors.add("Error " + saxExp);
            }
        }
    }

    /**
     * Returns the number of general errors (considered caught exceptions).
     */
    public List<String> getGeneralErrors() {
        return mGeneralErrors;
    }

    /**
     * Sets the files to be tested.
     */
    public void setLayoutFiles(List<InputSource> layoutFiles) {
        this.mLayoutFiles = layoutFiles;
    }

    /**
     * Gets the files to be tested.
     */
    public List<InputSource> getLayoutFiles() {
        return mLayoutFiles;
    }

    /**
     * Gets the total number of test validation errors across all files.
     */
    public int getTotalValidationErrors() {
        return mTotalValidationErrors;
    }
}
