/*
 * Copyright 2016-present Open Networking Laboratory
 *
 * 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.onosproject.checkstyle;

import com.puppycrawl.tools.checkstyle.Checker;
import com.puppycrawl.tools.checkstyle.ConfigurationLoader;
import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
import com.puppycrawl.tools.checkstyle.PropertiesExpander;
import com.puppycrawl.tools.checkstyle.api.AuditEvent;
import com.puppycrawl.tools.checkstyle.api.AuditListener;
import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
import com.puppycrawl.tools.checkstyle.api.Configuration;
import org.onosproject.buckdaemon.BuckTask;
import org.onosproject.buckdaemon.BuckTaskContext;

import java.io.File;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.stream.Collectors;

import static com.google.common.base.Strings.isNullOrEmpty;

/**
 * Buck task for executing checkstyle on the specified project files.
 */
public class CheckstyleRunner implements BuckTask {

    private final Configuration config;

    public CheckstyleRunner(String configLocation, String suppressionLocation) {
        try {
            // create a configuration
            DefaultConfiguration config = (DefaultConfiguration) ConfigurationLoader
                    .loadConfiguration(configLocation, new PropertiesExpander(System.getProperties()));

            // add the suppression file to the configuration
            DefaultConfiguration suppressions = new DefaultConfiguration("SuppressionFilter");
            suppressions.addAttribute("file", suppressionLocation);
            config.addChild(suppressions);

            this.config = config;
        } catch (CheckstyleException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void execute(BuckTaskContext context) {
        List<String> input = context.input();
        if (input.size() < 3 || input.get(2).length() == 0) {
            return;
        }
        String project = input.get(0);
        String baseDir = input.get(1);

        // create a listener for output
        StringAuditor listener = new StringAuditor(context);
        listener.setProjectName(project);
        listener.setBaseDir(baseDir);

        // create Checker object and run it
        final Checker checker = new Checker();
        final ClassLoader moduleClassLoader = Checker.class.getClassLoader();
        checker.setModuleClassLoader(moduleClassLoader);

        try {
            checker.configure(config);
            checker.addListener(listener);

            // run Checker
            List<File> fileList = input.subList(2, input.size() - 1).stream()
                    .map(File::new)
                    .collect(Collectors.toList());
            int errorCounter = checker.process(fileList);
            if (errorCounter > 0) {
                context.output("CHECKSTYLE ERROR");
            }

            listener.await();
        } catch (CheckstyleException | InterruptedException e) {
            e.printStackTrace(); //dump exeception to stderr
            throw new RuntimeException(e);
        } finally {
            checker.destroy();
        }

    }

    static class StringAuditor implements AuditListener {

        private final BuckTaskContext context;
        private CountDownLatch finishedLatch = new CountDownLatch(1);
        private String baseDir = "";
        private String project = "";

        StringAuditor(BuckTaskContext context) {
            this.context = context;
        }

        public void setBaseDir(String base) {
            this.baseDir = base;
        }

        public void setProjectName(String projectName) {
            this.project = projectName;
        }

        public void await() throws InterruptedException {
            finishedLatch.await();
        }

        @Override
        public void auditStarted(AuditEvent evt) {
        }

        @Override
        public void auditFinished(AuditEvent evt) {
            finishedLatch.countDown();
        }

        @Override
        public void fileStarted(AuditEvent evt) {
        }

        @Override
        public void fileFinished(AuditEvent evt) {
        }

        @Override
        public void addError(AuditEvent evt) {
            switch (evt.getSeverityLevel()) {
                case ERROR:
                    StringBuilder output = new StringBuilder();
                    String fileName = evt.getFileName();
                    if (!isNullOrEmpty(baseDir)) {
                        int index = fileName.indexOf(baseDir);
                        if (index >= 0) {
                            fileName = fileName.substring(index + baseDir.length() + 1);
                            if (!isNullOrEmpty(project)) {
                                output.append(project).append(':');
                            }
                        }
                    }
                    output.append(fileName).append(':').append(evt.getLine());
                    if (evt.getColumn() > 0) {
                        output.append(':').append(evt.getColumn());
                    }
                    output.append(": ").append(evt.getMessage());
                    context.output(output.toString());
                    break;
                case IGNORE:
                case INFO:
                case WARNING:
                default:
                    break;
            }
        }

        @Override
        public void addException(AuditEvent evt, Throwable throwable) {
            addError(evt);
            context.output(throwable.getMessage());
        }
    }

}
