package org.chromium.devtools.jsdoc;

import com.google.javascript.jscomp.Compiler;
import com.google.javascript.jscomp.NodeTraversal;
import com.google.javascript.jscomp.parsing.Config;
import com.google.javascript.jscomp.parsing.Config.JsDocParsing;
import com.google.javascript.jscomp.parsing.Config.LanguageMode;
import com.google.javascript.jscomp.parsing.Config.StrictMode;
import com.google.javascript.jscomp.parsing.Config.RunMode;
import com.google.javascript.jscomp.parsing.ParserRunner;
import com.google.javascript.rhino.ErrorReporter;
import com.google.javascript.rhino.Node;

import org.chromium.devtools.jsdoc.checks.ContextTrackingValidationCheck;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Callable;

public class FileCheckerCallable implements Callable<ValidatorContext> {
    private static Set<String> EXTRA_ANNOTATIONS =
            new HashSet<>(Arrays.asList("suppressReceiverCheck", "suppressGlobalPropertiesCheck"));
    private final String fileName;

    public FileCheckerCallable(String fileName) {
        this.fileName = fileName;
    }

    @Override
    public ValidatorContext call() {
        try {
            ValidatorContext context = new ValidatorContext(readScriptText(), fileName);
            ValidationCheckDispatcher dispatcher = new ValidationCheckDispatcher(context);
            dispatcher.registerCheck(new ContextTrackingValidationCheck());
            NodeTraversal.traverseEs6ScopeRoots(new Compiler(), parseScript(context), null, dispatcher, true);
            return context;
        } catch (FileNotFoundException e) {
            logError("File not found: " + fileName);
        } catch (IOException e) {
            logError("Failed to read file " + fileName);
        }
        return null;
    }

    private String readScriptText() throws IOException {
        byte[] encoded = Files.readAllBytes(FileSystems.getDefault().getPath(fileName));
        String text = StandardCharsets.UTF_8.decode(ByteBuffer.wrap(encoded)).toString();
        return text;
    }

    private static Node parseScript(final ValidatorContext context) {
        Config config = ParserRunner.createConfig(LanguageMode.ECMASCRIPT6,
                JsDocParsing.INCLUDE_DESCRIPTIONS_WITH_WHITESPACE, RunMode.KEEP_GOING,
                EXTRA_ANNOTATIONS, true, StrictMode.STRICT);
        ErrorReporter errorReporter = new ErrorReporter() {
            @Override
            public void warning(String message, String sourceName, int line, int lineOffset) {
                // Ignore.
            }

            @Override
            public void error(String message, String sourceName, int line, int lineOffset) {
                logError("at " + sourceName + ":" + line + ":" + lineOffset);
            }
        };
        try {
            return ParserRunner
                    .parse(context.sourceFile, context.sourceFile.getCode(), config, errorReporter)
                    .ast;
        } catch (IOException e) {
            // Does not happen with preloaded files.
            return null;
        }
    }

    private static void logError(String message) {
        System.err.println("ERROR: " + message);
    }

    private static class ValidationCheckDispatcher extends DoDidVisitorAdapter {
        private final List<ValidationCheck> checks = new ArrayList<>(2);
        private final ValidatorContext context;

        public ValidationCheckDispatcher(ValidatorContext context) {
            this.context = context;
        }

        public void registerCheck(ValidationCheck check) {
            check.setContext(context);
            checks.add(check);
        }

        @Override
        public void doVisit(Node node) {
            for (DoDidNodeVisitor visitor : checks) {
                visitor.doVisit(node);
            }
        }

        @Override
        public void didVisit(Node node) {
            for (ValidationCheck check : checks) {
                check.didVisit(node);
            }
        }
    }
}
