/*
 * Copyright 2012 Google Inc.
 *
 * 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 com.google.gwt.dev.js;

import com.google.gwt.dev.jjs.InternalCompilerException;
import com.google.gwt.dev.jjs.SourceInfo;
import com.google.gwt.dev.jjs.ast.Context;
import com.google.gwt.dev.jjs.ast.JClassLiteral;
import com.google.gwt.dev.jjs.ast.JConstructor;
import com.google.gwt.dev.jjs.ast.JDeclarationStatement;
import com.google.gwt.dev.jjs.ast.JExpression;
import com.google.gwt.dev.jjs.ast.JField;
import com.google.gwt.dev.jjs.ast.JMethodCall;
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.dev.jjs.ast.JThisRef;
import com.google.gwt.dev.jjs.ast.JValueLiteral;
import com.google.gwt.dev.jjs.ast.JVisitor;
import com.google.gwt.dev.jjs.ast.js.JsniMethodBody;
import com.google.gwt.dev.js.ast.JsContext;
import com.google.gwt.dev.js.ast.JsExpression;
import com.google.gwt.thirdparty.guava.common.base.Charsets;
import com.google.gwt.thirdparty.guava.common.collect.HashMultimap;
import com.google.gwt.thirdparty.guava.common.collect.ImmutableSet;
import com.google.gwt.thirdparty.guava.common.collect.Multimap;
import com.google.gwt.thirdparty.guava.common.collect.Sets;
import com.google.gwt.thirdparty.guava.common.io.Files;

import java.io.File;
import java.io.IOException;
import java.util.Set;

/**
 * Build up a collection of all instrumentable lines, useful for generating
 * coverage reports.
 */
public class BaselineCoverageGatherer {

  public static Multimap<String, Integer> exec(JProgram jProgram) {
    return new BaselineCoverageGatherer(jProgram, getCoveredSourceFiles()).execImpl();
  }

  private static Set<String> getCoveredSourceFiles() {
    String filename = System.getProperty(CoverageInstrumentor.GWT_COVERAGE_SYSTEM_PROPERTY);
    if (filename.indexOf(',') != -1) {
      return ImmutableSet.copyOf(filename.split(","));
    }
    File instrumentationFile = new File(filename);
    try {
      return Sets.newHashSet(Files.readLines(instrumentationFile, Charsets.UTF_8));
    } catch (IOException e) {
      throw new InternalCompilerException("Could not open " + filename, e);
    }
  }

  private Multimap<String, Integer> instrumentableLines = HashMultimap.create();
  private Set<String> instrumentedFiles;
  private JProgram jProgram;

  private BaselineCoverageGatherer(JProgram jProgram, Set<String> instrumentedFiles) {
    this.jProgram = jProgram;
    this.instrumentedFiles = instrumentedFiles;
  }

  private void cover(SourceInfo info) {
    if (instrumentedFiles.contains(info.getFileName())) {
      instrumentableLines.put(info.getFileName(), info.getStartLine());
    }
  }

  private Multimap<String, Integer> execImpl() {
    /**
     * Figure out which lines are executable. This is mostly straightforward
     * except that we have to avoid some synthetic nodes introduced earlier,
     * otherwise e.g. class declarations will be visited.
     */
    new JVisitor() {
      @Override public void endVisit(JMethodCall x, Context ctx) {
        // this is a bit of a hack. The compiler inserts no-arg super calls, but
        // there isn't really a way to detect that they're synthetic, and the
        // strategy below of comparing source info with that of the enclosing type
        // doesn't work because the enclosing type is set to be that of the superclass.
        if (x.getTarget().isSynthetic()
            || (x.getTarget().isConstructor()
                && ((JConstructor) x.getTarget()).isDefaultConstructor())) {
          return;
        }
        endVisit((JExpression) x, ctx);
      }

      @Override public void endVisit(JThisRef x, Context ctx) {
        if (x.getSourceInfo().equals(x.getClassType().getSourceInfo())) {
          return;
        }
        endVisit((JExpression) x, ctx);
      }

      @Override public void endVisit(JClassLiteral x, Context ctx) {
        if (x.getSourceInfo().equals(x.getRefType().getSourceInfo())) {
          return;
        }
        endVisit((JExpression) x, ctx);
      }

      @Override public void endVisit(JExpression x, Context ctx) {
        cover(x.getSourceInfo());
      }

      @Override public void endVisit(JsniMethodBody x, Context ctx) {
        new CoverageVisitor(instrumentedFiles) {
          @Override public void endVisit(JsExpression x, JsContext ctx) {
            cover(x.getSourceInfo());
          }
        }.accept(x.getFunc());
      }

      // don't instrument fields whose initializers are literals, because (1) CoverageVisitor
      // doesn't visit literals because it can introduce syntax errors in some cases, and (2) it's
      // consistent with other coverage tools, e.g. Emma.
      @Override public boolean visit(JDeclarationStatement x, Context ctx) {
        return !(x.getInitializer() instanceof JValueLiteral &&
            x.getVariableRef().getTarget() instanceof JField);
      }

      // don't instrument method call arguments; we can get weird coverage results when a call is
      // spread over several lines
      @Override public boolean visit(JMethodCall x, Context ctx) {
        return false;
      }
    }.accept(jProgram);
    return instrumentableLines;
  }
}
