/*
 * Copyright 2009 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.core.linker;

import com.google.gwt.core.ext.Linker;
import com.google.gwt.core.ext.LinkerContext;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.linker.Artifact;
import com.google.gwt.core.ext.linker.ArtifactSet;
import com.google.gwt.core.ext.linker.CompilationResult;
import com.google.gwt.core.ext.linker.EmittedArtifact;
import com.google.gwt.core.ext.linker.EmittedArtifact.Visibility;
import com.google.gwt.core.ext.linker.LinkerOrder;
import com.google.gwt.core.ext.linker.LinkerOrder.Order;
import com.google.gwt.core.ext.linker.ModuleMetricsArtifact;
import com.google.gwt.core.ext.linker.SelectionProperty;
import com.google.gwt.core.ext.linker.Shardable;
import com.google.gwt.core.ext.linker.SyntheticArtifact;
import com.google.gwt.core.ext.linker.Transferable;
import com.google.gwt.soyc.CompilerMetricsXmlFormatter;
import com.google.gwt.soyc.SoycDashboard;
import com.google.gwt.soyc.io.ArtifactsOutputDirectory;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

/**
 * Converts SOYC report files into emitted private artifacts.
 */
@LinkerOrder(Order.POST)
@Shardable
public class SoycReportLinker extends Linker {
  /**
   * An artifact giving a one-line description of a permutation ID in terms of
   * its deferred bindings.
   */
  @Transferable
  private static class PermDescriptionArtifact extends
      Artifact<PermDescriptionArtifact> {

    private List<String> permDesc;
    private int permId;

    public PermDescriptionArtifact(int permId, List<String> permDesc) {
      super(SoycReportLinker.class);
      this.permId = permId;
      this.permDesc = permDesc;
    }

    public List<String> getPermDesc() {
      return permDesc;
    }

    public int getPermId() {
      return permId;
    }

    @Override
    public int hashCode() {
      return permId;
    }

    @Override
    protected int compareToComparableArtifact(PermDescriptionArtifact o) {
      int cmp;
      cmp = permId - o.getPermId();
      if (cmp != 0) {
        return cmp;
      }

      cmp = permDesc.size() - o.getPermDesc().size();
      if (cmp != 0) {
        return cmp;
      }

      for (int i = 0; i < permDesc.size(); i++) {
        cmp = permDesc.get(i).compareTo(o.getPermDesc().get(i));
        if (cmp != 0) {
          return cmp;
        }
      }

      return 0;
    }

    @Override
    protected Class<PermDescriptionArtifact> getComparableArtifactType() {
      return PermDescriptionArtifact.class;
    }
  }

  @Override
  public String getDescription() {
    return "Emit compile report artifacts";
  }

  @Override
  public ArtifactSet link(TreeLogger logger, LinkerContext context,
      ArtifactSet artifacts, boolean onePermutation) {

    boolean reportFilesPresent = anyReportFilesPresent(artifacts);
    boolean metricsPresent = anyCompilerMetricsPresent(artifacts);

    if (!reportFilesPresent && !metricsPresent) {
      return artifacts;
    }

    artifacts = new ArtifactSet(artifacts);

    if (!onePermutation) {
      buildCompilerMetricsXml(artifacts);
    }

    if (reportFilesPresent) {
      if (onePermutation) {
        emitPermutationDescriptions(artifacts);
      } else {
        buildTopLevelFiles(logger, artifacts);
      }
    }

    return artifacts;
  }

  /**
   * Check whether an artifact set contains any compilerMetrics.
   */
  boolean anyCompilerMetricsPresent(ArtifactSet artifacts) {
    return  !artifacts.find(ModuleMetricsArtifact.class).isEmpty();
  }

  /**
   * Check whether an artifact set contains any SOYC report documents.
   */
  boolean anyReportFilesPresent(ArtifactSet artifacts) {
    String prefix1 = ArtifactsOutputDirectory.COMPILE_REPORT_DIRECTORY + "/";
    String prefix2 = "soycReport/" + prefix1;

    for (EmittedArtifact art : artifacts.find(EmittedArtifact.class)) {
      if (art.getPartialPath().startsWith(prefix1)) {
        return true;
      }
      if (art.getPartialPath().startsWith(prefix2)) {
        return true;
      }
    }

    return false;
  }

  /**
   * Compiler Metrics are captured in the module load, precompilation,
   * and compile permutations step, then all merged together into a single
   * XML file as output.  That file can then be consumed by external
   * reporting tools.
   */
  private void buildCompilerMetricsXml(ArtifactSet artifacts) {
    ModuleMetricsArtifact moduleMetrics = null;
    Set<ModuleMetricsArtifact> moduleMetricsSet = artifacts.find(
        ModuleMetricsArtifact.class);
    if (!moduleMetricsSet.isEmpty()) {
      for (ModuleMetricsArtifact metrics : moduleMetricsSet) {
        moduleMetrics = metrics;
        // We only need one module metrics definition.
        break;
      }
    }

    // No module metrics? Then we'll skip creating the compilerMetrics output
    if (moduleMetrics == null) {
      return;
    }

    byte[] xmlResult = CompilerMetricsXmlFormatter.writeMetricsAsXml(
        artifacts, moduleMetrics);
    EmittedArtifact metricsArtifact = new SyntheticArtifact(
        SoycReportLinker.class, "compilerMetrics.xml", xmlResult);
    metricsArtifact.setVisibility(Visibility.Private);
    artifacts.add(metricsArtifact);
  }

  private void buildTopLevelFiles(TreeLogger logger,
      ArtifactSet artifacts) {
    ArtifactsOutputDirectory out = new ArtifactsOutputDirectory();
    try {
      new SoycDashboard(out).generateCrossPermutationFiles(
          extractPermutationDescriptions(artifacts));
    } catch (IOException e) {
      logger.log(TreeLogger.ERROR,
          "Error while generating a Story of Your Compile", e);
      e.printStackTrace();
    }

    artifacts.addAll(out.getArtifacts());
  }

  private void emitPermutationDescriptions(ArtifactSet artifacts) {
    for (CompilationResult res : artifacts.find(CompilationResult.class)) {
      int permId = res.getPermutationId();
      List<String> permDesc = new ArrayList<String>();
      for (Map<SelectionProperty, String> propertyMap : res.getPropertyMap()) {
        permDesc.add(SymbolMapsLinker.propertyMapToString(propertyMap));
      }

      artifacts.add(new PermDescriptionArtifact(permId, permDesc));
    }
  }

  private Map<String, List<String>> extractPermutationDescriptions(
      ArtifactSet artifacts) {
    Map<String, List<String>> permDescriptions = new TreeMap<String,
        List<String>>();
    for (PermDescriptionArtifact art : artifacts.find(
        PermDescriptionArtifact.class)) {
      permDescriptions.put(Integer.toString(art.getPermId()),
          art.getPermDesc());
    }
    return permDescriptions;
  }
}
