/*
 * ******************************************************************************
 * Copyright (C) 2007, International Business Machines Corporation and others.
 * All Rights Reserved.
 * ******************************************************************************
 */
package com.ibm.icu.dev.tool.tzu;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import javax.swing.AbstractListModel;

/**
 * Represents a list of IncludePaths that is usable by any class that uses AbstractListModels (such
 * as a JList in swing). Also contains methods to begin a search on those paths using ICUJarFinder
 * and placing the results in a ResultModel, and methods to load a path list from a file.
 */
class PathModel extends AbstractListModel {
    /**
     * The serializable UID.
     */
    public static final long serialVersionUID = 1337;

    /**
     * The list of paths as IncludePaths.
     */
    private List list = new ArrayList();

    /**
     * The current logger.
     */
    private Logger logger;

    /**
     * The paths file where the paths are stored.
     */
    private File pathListFile;

    /**
     * The filename of the paths file where the paths are stored.
     */
    private String pathListFilename;

    /**
     * Constructs an empty path model.
     * 
     * @param pathFile
     *            The file to load the path list from.
     * @param logger
     *            The current logger.
     */
    public PathModel(Logger logger, File pathFile) {
        this.logger = logger;
        this.pathListFile = pathFile;
        this.pathListFilename = pathFile.getName();
    }

    /**
     * Adds an IncludePath to the path list if it exists and is unique.
     * 
     * @param path
     *            An existing path.
     * @return Whether or not the given IncludePath exists.
     */
    public boolean add(IncludePath path) {
        remove(path);

        if (path.getPath().exists()) {
            list.add(path);
            int index = list.size() - 1;
            fireIntervalAdded(this, index, index);
            return true;
        }

        return false;
    }

    /**
     * Adds a filename to the path list if it is valid and unique. The filename must either be of
     * the form (<b>+</b>|<b>-</b>)<i>pathstring</i> and exist, or of the form <b>all</b>. In
     * the case of the latter, all drives are added to the path list.
     * 
     * @param includeFilename
     *            A filename in the form above.
     * @return Whether or not <code>includeFilename</code> is both of the form detailed above and
     *         exists.
     */
    public boolean add(String includeFilename) {
        if ("all".equalsIgnoreCase(includeFilename)) {
            logger
                    .printlnToScreen("The tool will search all drives for ICU4J jars except any excluded directories specified");
            addAllDrives();
            return true;
        }

        return add(new IncludePath(new File(includeFilename.substring(1).trim()), includeFilename
                .charAt(0) == '+'));
    }

    /**
     * Adds all drives to the path list.
     */
    public void addAllDrives() {
        File[] roots = File.listRoots();
        for (int i = 0; i < roots.length; i++)
            add(new IncludePath(roots[i], true));
    }

    /**
     * Returns the path at the element at a particular index of the path list.
     * 
     * @param index
     *            The index of the element of the path list to return.
     * @return The path at the specified index of the path list. Guaranteed to always be an
     *         IncludePath.
     */
    public Object getElementAt(int index) {
        return list.get(index);
    }

    /**
     * Returns the size of the path list.
     * 
     * @return The size of the path list.
     */
    public int getSize() {
        return (list == null) ? 0 : list.size();
    }

    /**
     * Returns an iterator of the path list.
     * 
     * @return An iterator of the path list.
     */
    public Iterator iterator() {
        return list.iterator();
    }

    /**
     * Loads a list of paths from the given path list file. Each path must be of the form
     * 
     * @throws IOException
     * @throws IllegalArgumentException
     */
    public void loadPaths() throws IOException, IllegalArgumentException {
        logger.printlnToBoth("Scanning " + pathListFilename + " file...");
        logger.loglnToBoth(pathListFilename + " file contains");

        BufferedReader reader = null;
        int lineNumber = 0;
        String line;
        char sign;

        try {
            reader = new BufferedReader(new InputStreamReader(new FileInputStream(pathListFile),
                    "UTF-8"), 4 * 1024);
            while ((line = reader.readLine()) != null) {
                if (line.length() >= 1 && line.charAt(0) == '\ufeff')
                    line = line.substring(1);
                line = line.trim();
                lineNumber++;

                if (line.length() >= 1 && (sign = line.charAt(0)) != '#') {
                    if (sign != '+' && sign != '-' && !"all".equalsIgnoreCase(line)) {
                        String error = "Each path entry must start with a + or - to denote inclusion/exclusion";
                        pathListError(error, lineNumber);
                        continue;
                    }
                    if (!add(line)) {
                        String error = line.substring(1).trim()
                                + " is not a valid file or directory (perhaps it does not exist?)";
                        pathListError(error, lineNumber);
                        continue;
                    }
                    logger.printlnToBoth(line);
                }
            }
            logger.printlnToBoth("Scanning " + pathListFilename + " complete.");
        } catch (FileNotFoundException ex) {
            pathListError("The " + pathListFilename + " file doesn't exist.");
        } catch (IOException ex) {
            pathListError("Could not read the " + pathListFilename + " file.");
        } finally {
            try {
                if (reader != null)
                    reader.close();
            } catch (IOException ex) {
            }
        }
    }

    /**
     * Removes a path from the path list. Since there are no duplicates in the path list, this
     * method either removes a single path or removes none.
     * 
     * @param path
     *            The path to remove from the path list.
     */
    public void remove(IncludePath path) {
        int index = list.indexOf(path);
        if (index != -1) {
            list.remove(index);
            fireIntervalRemoved(this, index, index);
        }
    }

    /**
     * Removes a selection of paths from the path list by index.
     * 
     * @param indices
     *            The indices of the path list to remove.
     */
    public void remove(int[] indices) {
        if (list.size() > 0 && indices.length > 0) {
            Arrays.sort(indices);
            int max = indices[indices.length - 1];
            int min = indices[0];
            for (int i = indices.length - 1; i >= 0; i--)
                list.remove(indices[i]);
            fireIntervalRemoved(this, min, max);
        }
    }

    /**
     * Clears the path list.
     */
    public void removeAll() {
        if (list.size() > 0) {
            int index = list.size() - 1;
            list.clear();
            fireIntervalRemoved(this, 0, index);
        }
    }

    /**
     * Searches a selection of paths in the path list for updatable ICU4J jars. Results are added to
     * the result model. The indices provided are the indices of the path list to search.
     * 
     * @param resultModel
     *            The result model to store the results of the search.
     * @param indices
     *            The indices of the path list to use in the search.
     * @param subdirs
     *            Whether to search subdiretories.
     * @param curDir
     *            The base directory of the tool.
     * @param backupDir
     *            Where to store backup files.
     * @throws InterruptedException
     */
    public void search(ResultModel resultModel, int[] indices, boolean subdirs, File curDir,
            File backupDir) throws InterruptedException {
        if (list.size() > 0 && indices.length > 0) {
            Arrays.sort(indices);
            int n = indices.length;
            IncludePath[] paths = new IncludePath[n];

            int k = 0;
            Iterator iter = iterator();
            for (int i = 0; k < n && iter.hasNext(); i++)
                if (i == indices[k])
                    paths[k++] = (IncludePath) iter.next();
                else
                    iter.next();

            ICUJarFinder.search(resultModel, logger, paths, subdirs, curDir, backupDir);
        }
    }

    /**
     * Searches each path in the path list for updatable ICU4J jars. Results are added to the result
     * model.
     * 
     * @param resultModel
     *            The result model to store the results of the search.
     * @param subdirs
     *            Whether to search subdiretories.
     * @param curDir
     *            The base directory of the tool.
     * @param backupDir
     *            Where to store backup files.
     * @throws InterruptedException
     */
    public void searchAll(ResultModel resultModel, boolean subdirs, File curDir, File backupDir)
            throws InterruptedException {
        if (list.size() > 0) {
            int n = list.size();
            IncludePath[] paths = new IncludePath[n];
            Iterator iter = iterator();
            for (int i = 0; i < n; i++)
                paths[i] = (IncludePath) iter.next();
            ICUJarFinder.search(resultModel, logger, paths, subdirs, curDir, backupDir);
        }
    }

    /**
     * Throws an IOException with the specified message.
     * 
     * @param message
     *            The message to put in the exception.
     * @throws IOException
     */
    private void pathListError(String message) throws IOException {
        throw new IOException("Error in " + pathListFilename + ": " + message);
    }

    /**
     * Logs as an error a specified message and line number.
     * 
     * @param message
     *            The message to put in the exception.
     * @param lineNumber
     *            The line number to put in the exception.
     */
    private void pathListError(String message, int lineNumber) {
        logger.printlnToBoth("Error in " + pathListFilename + " (line " + lineNumber + "): "
                + message);
    }
}
