/**
 * Validator for Closure-based JSDoc.
 */

package org.chromium.devtools.jsdoc;

import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class JsDocValidator {
    private static final String FILES_LIST_NAME = "--files-list-name";

    private void run(String[] args) {
        if (args.length == 0) {
            System.err.println("At least 1 argument is expected");
            System.exit(1);
        }
        String[] files;
        if (FILES_LIST_NAME.equals(args[0])) {
            files = readFileNames(args);
        } else {
            files = args;
        }
        int threadCount = Math.min(files.length, Runtime.getRuntime().availableProcessors());
        ExecutorService executor = Executors.newFixedThreadPool(threadCount);
        try {
            runWithExecutor(files, executor);
        } finally {
            executor.shutdown();
        }
    }

    private String[] readFileNames(String[] args) {
        if (args.length != 2) {
            System.err.println("A single file name is expected to follow " + FILES_LIST_NAME);
            System.exit(1);
        }
        try {
            List<String> list = Files.readAllLines(
                    FileSystems.getDefault().getPath(args[1]), Charset.forName("UTF-8"));
            return list.toArray(new String[list.size()]);
        } catch (IOException e) {
            System.err.println("Unable to read list file " + args[1]);
            e.printStackTrace();
            System.exit(1);
            return new String[0];
        }
    }

    private void runWithExecutor(String[] args, ExecutorService executor) {
        List<Future<ValidatorContext>> futures = new ArrayList<>(args.length);
        Map<Future<ValidatorContext>, String> fileNamesByFuture = new HashMap<>();
        for (String fileName : args) {
            Future<ValidatorContext> future = executor.submit(new FileCheckerCallable(fileName));
            fileNamesByFuture.put(future, fileName);
            futures.add(future);
        }

        List<ValidatorContext> contexts = new ArrayList<>(args.length);
        for (Future<ValidatorContext> future : futures) {
            try {
                ValidatorContext context = future.get();
                if (context != null) {
                    contexts.add(context);
                }
            } catch (InterruptedException | ExecutionException e) {
                if (e.getMessage().indexOf("DESTRUCTURING_LHS") == -1) {
                    System.err.println(
                            fileNamesByFuture.get(future) + ": ERROR - " + e.getMessage());
                }
            }
        }

        int entryCount = 0;
        for (ValidatorContext context : contexts) {
            entryCount += context.getValidationResult().size();
        }
        List<LogEntry> entries = new ArrayList<>(entryCount);
        for (ValidatorContext context : contexts) {
            SortedSet<ValidatorContext.MessageRecord> records = context.getValidationResult();
            for (ValidatorContext.MessageRecord record : records) {
                entries.add(new LogEntry(context.scriptFileName, record));
            }
        }
        Collections.sort(entries);
        for (LogEntry entry : entries) {
            System.err.println(entry.record.text);
        }
        if (!entries.isEmpty()) System.err.println("Total errors: " + entries.size());
    }

    public static void main(String[] args) {
        new JsDocValidator().run(args);
    }

    private static class LogEntry implements Comparable<LogEntry> {
        private final String fileName;
        private final ValidatorContext.MessageRecord record;

        LogEntry(String fileName, ValidatorContext.MessageRecord record) {
            this.fileName = fileName;
            this.record = record;
        }

        @Override
        public int compareTo(LogEntry other) {
            int result = fileName.compareTo(other.fileName);
            if (result != 0) {
                return result;
            }
            return Integer.compare(record.position, other.record.position);
        }

        @Override
        public int hashCode() {
            return 17 + fileName.hashCode() * 3 + this.record.hashCode() * 5;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            LogEntry other = (LogEntry) obj;
            if (fileName != other.fileName
                    && (fileName != null && !fileName.equals(other.fileName))) {
                return false;
            }

            if (record == other.record) {
                return true;
            }
            if (record != null) {
                if (other.record == null) {
                    return false;
                }
                return record.position == other.record.position;
            }
            return false;
        }
    }
}
