/*
 * ******************************************************************************
 * 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.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import javax.swing.table.AbstractTableModel;

/**
 * Represents a list of ICUFiles that is usable by any class that uses
 * AbstractTableModels (such as a JTable in swing). Also contains methods to
 * begin updates on those ICUFiles and methods to load and save a result list
 * from and to a file.
 */
class ResultModel extends AbstractTableModel {
    /**
     * The column designating filenames.
     */
    public static final int COLUMN_FILE_NAME = 0;

    /**
     * The column designating file paths.
     */
    public static final int COLUMN_FILE_PATH = 1;

    /**
     * The column designating ICU versions.
     */
    public static final int COLUMN_ICU_VERSION = 2;

    /**
     * The column designating timezone verisons.
     */
    public static final int COLUMN_TZ_VERSION = 3;

    /**
     * A list of names of the columns in a result model.
     */
    public static final String[] COLUMN_NAMES = new String[] { "Filename",
            "Path", "ICU Version", "TZ Version" };

    /**
     * The serializable UID.
     */
    public static final long serialVersionUID = 1338;

    /**
     * The list of ICUFiles represented by this result model.
     */
    private List icuFileList = new ArrayList();

    /**
     * The current logger.
     */
    private Logger logger;

    /**
     * The result list file where results are saved and stored.
     */
    private File resultListFile;

    /**
     * The filename of the result list file where results are saved and stored.
     */
    private String resultListFilename;

    /**
     * Constructs an empty result list.
     * 
     * @param resultFile
     *            The file to load and save results from and to.
     * @param logger
     *            The current logger.
     */
    public ResultModel(Logger logger, File resultFile) {
        this.logger = logger;
        this.resultListFile = resultFile;
        this.resultListFilename = resultFile.getName();
    }

    /**
     * Adds a file to the ICUFile list.
     * 
     * @param file
     *            The file.
     * @return Whether the file was added successfully (which is determined by
     *         if it is an updatable ICU4J jar).
     */
    public boolean add(File file) {
        try {
            ICUFile icuFile = new ICUFile(file, logger);
            add(icuFile);
            return true;
        } catch (IOException ex) {
            return false;
        }
    }

    /**
     * Adds a file to the ICUFile list.
     * 
     * @param icuFile
     *            The file.
     */
    public void add(ICUFile icuFile) {
        remove(icuFile.getFile());
        icuFileList.add(icuFile);
        int index = icuFileList.size() - 1;
        fireTableRowsInserted(index, index);
    }

    /**
     * Adds a file to the ICUFile list.
     * 
     * @param filename
     *            The name of the file.
     * @return Whether the file was added successfully (which is determined by
     *         if it is an updatable ICU4J jar).
     */
    public boolean add(String filename) {
        return add(new File(filename));
    }

    /**
     * Returns the number of columns for each represented ICUFile.
     * 
     * @return The number of columns for each represented ICUFile.
     */
    public int getColumnCount() {
        return COLUMN_NAMES.length;
    }

    /**
     * Returns the column names as stored in COLUMN_NAMES.
     * 
     * @param col
     *            The index of the column.
     * @return <code>COLUMN_NAMES[col]</code>
     */
    public String getColumnName(int col) {
        return COLUMN_NAMES[col];
    }

    /**
     * Returns the number of ICUFiles represented.
     * 
     * @return The number of ICUFiles represented.
     */
    public int getRowCount() {
        return (icuFileList == null) ? 0 : icuFileList.size();
    }

    /**
     * Returns the item at the given row and column. The row determines which
     * ICUFile is used, and the column determines which piece of data should be
     * used.
     * 
     * @param row
     *            Which ICU file to use.
     * @param col
     *            Which piece of data to use. Should be one of the following:
     *            <ul>
     *            <li>COLUMN_FILE_PATH</li>
     *            <li>COLUMN_ICU_VERSION</li>
     *            <li>COLUMN_TZ_VERSION</li>
     *            </ul>
     * @return The item at the given row and column. Will always be a String.
     */
    public Object getValueAt(int row, int col) {
        ICUFile icuFile = ((ICUFile) icuFileList.get(row));
        switch (col) {
        case COLUMN_FILE_NAME:
            return icuFile.getFilename();
        case COLUMN_FILE_PATH:
            return icuFile.getPath();
        case COLUMN_ICU_VERSION:
            return icuFile.getICUVersion();
        case COLUMN_TZ_VERSION:
            return icuFile.getTZVersion();
        default:
            return null;
        }
    }

    /**
     * Returns an iterator on the list of ICUFiles.
     * 
     * @return An iterator on the list of ICUFiles.
     */
    public Iterator iterator() {
        return icuFileList.iterator();
    }

    /**
     * Loads a list of ICUFiles from the given result list file. Lines should be
     * of the form <b><i>pathstring</i><tab><i>tzversion</i></b>.
     * 
     * @throws IOException
     * @throws IllegalArgumentException
     */
    public void loadResults() throws IOException, IllegalArgumentException {
        logger.printlnToScreen("Scanning " + resultListFilename + " file...");
        logger.printlnToScreen(resultListFilename + " file contains");

        BufferedReader reader = null;
        int lineNumber = 1;
        String line;
        int tab;
        String filename;

        try {
            reader = new BufferedReader(new InputStreamReader(
                    new FileInputStream(resultListFile), "UTF-8"), 4 * 1024);
            while ((line = reader.readLine()) != null) {
                if (line.length() >= 1 && line.charAt(0) == '\ufeff')
                    line = line.substring(1);
                line = line.trim();
                logger.printlnToScreen(line);

                if (line.length() >= 1 && (tab = line.lastIndexOf('\t')) >= 0) {
                    if (!add(filename = line.substring(0, tab)))
                        resultListError(filename
                                + " is not an updatable ICU4J file", lineNumber);
                }

                lineNumber++;
            }
        } catch (FileNotFoundException ex) {
            resultListError("The "
                    + resultListFilename
                    + " file doesn't exist. Please re-run the tool with -Ddiscoveronly=true option to generate the list of ICU4J jars.");
        } catch (IOException ex) {
            resultListError("Could not read the "
                    + resultListFilename
                    + " file. Please re-run the tool with -Ddiscoveronly=true option to generate the list of ICU4J jars.");
        } finally {
            try {
                if (reader != null)
                    reader.close();
            } catch (IOException ex) {
            }
        }
    }

    /**
     * Removes a file from the ICUFile list.
     * 
     * @param file
     *            The file to remove.
     */
    public void remove(File file) {
        if (icuFileList.size() > 0) {
            Iterator iter = iterator();
            int i = 0;
            while (iter.hasNext()) {
                ICUFile icuFile = (ICUFile) iter.next();
                if (icuFile.getFile().getAbsoluteFile().equals(
                        file.getAbsoluteFile())) {
                    icuFileList.remove(icuFile);
                    fireTableRowsDeleted(i, i);
                    return;
                }
                i++;
            }
        }
    }

    /**
     * Removes a selection of files from the ICUFile list.
     * 
     * @param indices
     *            The indices of the files to remove.
     */
    public void remove(int[] indices) {
        if (icuFileList.size() > 0 && indices.length > 0) {
            Arrays.sort(indices);
            for (int i = indices.length - 1; i >= 0; i--) {
                icuFileList.remove(indices[i]);
                fireTableRowsDeleted(indices[i], indices[i]);
            }
        }
    }

    /**
     * Clears the ICUFile list.
     */
    public void removeAll() {
        if (icuFileList.size() > 0) {
            int lastIndex = icuFileList.size() - 1;
            icuFileList.clear();
            fireTableRowsDeleted(0, lastIndex);
        }
    }

    /**
     * Saves a list of ICUFiles to the given result list file. Lines will be of
     * the form <b><i>pathstring</i><tab><i>tzversion</i></b>.
     * 
     * @throws IOException
     * @throws IllegalArgumentException
     */
    public void saveResults() throws IOException, IllegalArgumentException {
        logger.printlnToScreen("Saving to file " + resultListFilename + " ...");
        BufferedWriter writer = null;
        ICUFile icuFile = null;

        try {
            writer = new BufferedWriter(new OutputStreamWriter(
                    new FileOutputStream(resultListFile), "UTF-8"), 4 * 1024);
            Iterator iter = iterator();
            while (iter.hasNext()) {
                icuFile = (ICUFile) iter.next();
                String line = icuFile.getFile().getPath() + '\t'
                        + icuFile.getTZVersion() + "\n";
                logger.printToScreen(line);
                writer.write(line);
            }
        } catch (FileNotFoundException ex) {
            resultListError("Could not create the " + resultListFilename
                    + " file.");
        } catch (IOException ex) {
            resultListError("Could not write to the " + resultListFilename
                    + " file.");
        } finally {
            try {
                if (writer != null)
                    writer.close();
            } catch (IOException ex) {
            }
        }
    }

    /**
     * Updates a selection of the ICUFiles given a URL as the source of the
     * update and a backup directory as a place to store a copy of the
     * un-updated file.
     * 
     * @param indices
     *            The indices of the ICUFiles to update.
     * @param updateURL
     *            The URL to use a source of the update.
     * @param backupDir
     *            The directory in which to store backups.
     * @throws InterruptedException
     */
    public void update(int[] indices, URL updateURL, File backupDir)
            throws InterruptedException {
        if (icuFileList.size() > 0 && indices.length > 0) {
            Arrays.sort(indices);
            int n = indices.length;

            int k = 0;
            Iterator iter = iterator();
            for (int i = 0; k < n && iter.hasNext(); i++)
                if (i == indices[k])
                    try {
                        // update the file
                        ((ICUFile) iter.next()).update(updateURL, backupDir);
                        fireTableRowsUpdated(i, i);
                        k++;
                    } catch (IOException ex) {
                        // could not update the jar
                        logger.errorln(ex.getMessage());
                    }
                else
                    iter.next();
        }
    }

    /**
     * Updates all of the ICUFiles given a URL as the source of the update and a
     * backup directory as a place to store a copy of the un-updated file.
     * 
     * @param updateURL
     *            The URL to use a source of the update.
     * @param backupDir
     *            The directory in which to store backups.
     * @throws InterruptedException
     */
    public void updateAll(URL updateURL, File backupDir)
            throws InterruptedException {
        if (icuFileList.size() > 0) {
            int n = icuFileList.size();
            Iterator iter = iterator();
            for (int i = 0; i < n; i++)
                try {
                    ((ICUFile) iter.next()).update(updateURL, backupDir);
                    fireTableRowsUpdated(i, i);
                } catch (IOException ex) {
                    // could not update the jar
                    logger.errorln(ex.getMessage());
                }
        }
    }

    /**
     * Throws an IllegalArgumentException with the given message.
     * 
     * @param message
     *            The message.
     * @throws IllegalArgumentException
     */
    private void resultListError(String message) throws IOException {
        throw new IOException("Error in " + resultListFilename + ": " + message);
    }

    /**
     * Throws an IllegalArgumentException with the given message and line
     * number.
     * 
     * @param message
     *            The message.
     * @param lineNumber
     *            The line number.
     */
    private void resultListError(String message, int lineNumber) {
        logger.errorln("Error in " + resultListFilename + " (line "
                + lineNumber + "): " + message);
    }
}
