/*
Copyright 2009 Martin Davis

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 org.jproj.cmd;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.jproj.CRSFactory;
import org.jproj.Proj4jException;
import org.jproj.io.MetaCRSTestCase;
import org.jproj.io.MetaCRSTestFileReader;
import org.jproj.util.CRSCache;

/**
 * A command-line application which runs test files 
 * in MetaCRS Transformation Test format.
 * <p>
 * Usage:
 * <pre>
 *   MetaCRSTestCmd <test-file-name>
 * </pre>
 * 
 * @author Martin Davis
 *
 */
public class MetaCRSTestCmd {
        // TODO: display line numbers of tests in verbose mode

        public static void main(String args[]) {
                MetaCRSTestCmd cmd = new MetaCRSTestCmd();
                cmd.parseArgs(args);
                try {
                        cmd.execute();
                } catch (Exception ex) {
                        ex.printStackTrace();
                }
        }

        private static String usage() {
                return "Usage: MetaCRSTestCmd [-verbose] { <test-file-name> }";
        }
        private static final int TESTS_PER_LINE = 50;
        private static CRSFactory csFactory = new CRSFactory();
        private List<String> filenames = new ArrayList<String>();
        private boolean verbose = false;
        int count = 0;
        int failCount = 0;
        int errCount = 0;
        private CRSCache crsCache = new CRSCache();

        private void parseArgs(String[] args) {
                //TODO: error handling
                if (args.length <= 0) {
                        System.err.println(usage());
                        System.exit(1);
                }
                parseFlags(args);

                parseFiles(args);
        }

        private void parseFlags(String[] args) {
                for (String arg : args) {
                        if (arg.startsWith("-")) {
                                if (arg.equalsIgnoreCase("-verbose")) {
                                        verbose = true;
                                }
                        }
                }
        }

        private void parseFiles(String[] args) {
                for (String arg : args) {
                        if (!arg.startsWith("-")) {
                                filenames.add(arg);
                        }
                }
        }

        private void execute()
                throws IOException {
                long timeInMillis = System.currentTimeMillis();
                for (String filename : filenames) {
                        execute(filename);
                }

                System.out.println();
                System.out.println("Tests run: " + count
                        + ",  Failures: " + failCount
                        + ",  Errors: " + errCount);

                long timeMS = System.currentTimeMillis() - timeInMillis;
                System.out.println("Time: " + (timeMS / 1000.0) + " s");
        }

        private void execute(String filename)
                throws IOException {
                System.out.println("File: " + filename);

                File file = new File(filename);
                MetaCRSTestFileReader reader = new MetaCRSTestFileReader(file);
                List<MetaCRSTestCase> tests = reader.readTests();

                for (MetaCRSTestCase test : tests) {
                        test.setCache(crsCache);
                        count++;
                        System.out.print(".");
                        boolean isOk;
                        try {
                                isOk = test.execute(csFactory);
                        } catch (Proj4jException ex) {
                                System.out.println(ex);
                                errCount++;
                                continue;
                        }
                        if (!isOk) {
                                failCount++;
                                System.out.print("F");
                        }
                        if (verbose || !isOk) {
                                System.out.println();
                                test.print(System.out);
                        }

                        if (count % TESTS_PER_LINE == 0) {
                                System.out.println();
                        }
                }
                System.out.println();
        }
}
