package nl.codenizer.plugins.typescript;

import com.google.common.collect.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.batch.Sensor;
import org.sonar.api.batch.SensorContext;
import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.resources.Project;
import org.sonar.api.resources.Resource;

import java.io.File;
import java.util.List;

class TypeScriptSensor implements Sensor {
    private final FileSystem fileSystem;
    private final Logger log = LoggerFactory.getLogger(this.getClass());
    private AnalysisRunner analysisRunner;

    public TypeScriptSensor(FileSystem fileSystem) {
        this.fileSystem = fileSystem;
        this.analysisRunner = new AnalysisRunnerImpl();
    }

    private static Iterable<File> toFile(Iterable<InputFile> inputFiles) {
        List<File> files = Lists.newArrayList();
        for (InputFile inputFile : inputFiles) {
            files.add(inputFile.file());
        }
        return files;
    }

    public void setAnalysisRunner(AnalysisRunner runner) {
        this.analysisRunner = runner;
    }

    public boolean shouldExecuteOnProject(Project project) {
        // Only run if TypeScript files have been detected
        return this.fileSystem.hasFiles(this.fileSystem.predicates().hasLanguage(TypeScript.KEY));
    }

    public void analyse(Project project, SensorContext sensorContext) {
        Iterable<File> filesToAnalyze = GetFilesToAnalyze(this.fileSystem);

        for (File f : filesToAnalyze) {
            log.info("Will analyze " + f.getName());
        }

        File rootDir = fileSystem.baseDir();

        log.info("Analysing project root in search for TypeScript files: " + rootDir.getAbsolutePath());

        try {
            AnalysisResult[] result = this.analysisRunner.Execute(rootDir.getAbsolutePath());

            log.info("Analysis done, saving metrics");
            log.info("Got " + result.length + " metrics");

            for (AnalysisResult r : result) {
                saveCoreMetrics(sensorContext, r);
            }

            log.info("Metrics saved");
        } catch (Exception ae) {
            log.error("Error while running Analyzer:", ae);
            ae.printStackTrace(System.out);
        }
    }

    private void saveCoreMetrics(SensorContext sensorContext, AnalysisResult analysisResult) {
        InputFile file = new DefaultInputFile("someModule", analysisResult.getFileName());
        //log.info("found file: " + file.absolutePath());
        log.info("saving metrics for file " + analysisResult.getFileName());

        Resource resource = sensorContext.getResource(file);

        if (resource != null) {
            log.info("Found resource with language: " + resource.language());
        }

        log.debug("trying to save CoreMetrics.CLASSES");
        sensorContext.saveMeasure(resource, CoreMetrics.CLASSES, (double) analysisResult.getNumberOfClasses());

        log.debug("trying to save CoreMetrics.FUNCTIONS");
        sensorContext.saveMeasure(resource, CoreMetrics.FUNCTIONS, (double) analysisResult.getNumberOfMethods());

        log.debug("trying to save CoreMetrics.LINES");
        sensorContext.saveMeasure(resource, CoreMetrics.LINES, (double) analysisResult.getNumberOfLines());

        log.debug("trying to save CoreMetrics.NCLOC with value " + analysisResult.getLinesOfCode());
        sensorContext.saveMeasure(resource, CoreMetrics.NCLOC, (double) analysisResult.getLinesOfCode());

        log.debug("measures saved");
    }

    private Iterable<File> GetFilesToAnalyze(FileSystem fs) {
        Iterable<InputFile> files = fs.inputFiles(fs.predicates().hasLanguage(TypeScript.KEY));

        return toFile(files);
    }

    public String toString() {
        return "TypeScriptSensor";
    }
}
@@ -35,16 +35,101 @@
 cript;%0A%0A
+import com.google.common.base.Predicate;%0Aimport com.google.common.collect.Iterables;%0A
 import c
@@ -559,16 +559,50 @@
 ource;%0A%0A
+import javax.annotation.Nullable;%0A
 import j
@@ -1729,112 +1729,8 @@
 );%0A%0A
-        for (File f : filesToAnalyze) %7B%0A            log.info(%22Will analyze %22 + f.getName());%0A        %7D%0A%0A
     
@@ -2167,243 +2167,802 @@
     
-saveCoreMetrics(sensorContext, r);%0A            %7D%0A%0A            log.info(%22Metrics saved%22);%0A        %7D catch (Exception ae) %7B%0A            log.error(%22Error while running Analyzer:%22, ae);%0A            ae.printStackTrace(System.out);%0A        %7D
+File match = Iterables.find(filesToAnalyze, GetPredicateFor(r.getFileName()));%0A%0A                if(match != null) %7B%0A                    saveCoreMetrics(sensorContext, r, match);%0A                %7D else %7B%0A                    log.info(%22Skipping %22 + r.getFileName() + %22 because it is not included in the analysis for this project%22);%0A                %7D%0A            %7D%0A%0A            log.info(%22Metrics saved%22);%0A        %7D catch (Exception ae) %7B%0A            log.error(%22Error while running Analyzer:%22, ae);%0A            ae.printStackTrace(System.out);%0A        %7D%0A    %7D%0A%0A    private Predicate%3CFile%3E GetPredicateFor(final String fileName) %7B%0A        return new Predicate%3CFile%3E() %7B%0A            public boolean apply(@Nullable File file) %7B%0A                return file.getName() == fileName;%0A            %7D%0A        %7D;
 %0A   
@@ -3052,24 +3052,36 @@
 alysisResult
+, File match
 ) %7B%0A        
@@ -3136,96 +3136,26 @@
 e%22, 
-analysisResult.getFileName());%0A        //log.info(%22found file: %22 + file.absolutePath());
+match.getName());%0A
 %0A   
@@ -3295,129 +3295,8 @@
 );%0A%0A
-        if (resource != null) %7B%0A            log.info(%22Found resource with language: %22 + resource.language());%0A        %7D%0A%0A
     

Check if the file from the results is actually part of analysis and hasn't been excluded