/*
 * 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.LinkerOrder;
import com.google.gwt.core.ext.linker.SelectionProperty;
import com.google.gwt.core.ext.linker.Shardable;
import com.google.gwt.core.ext.linker.Transferable;
import com.google.gwt.core.ext.linker.LinkerOrder.Order;
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.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) {
    if (!anyReportFilesPresent(artifacts)) {
      // No report was generated
      return artifacts;
    }

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

  /**
   * 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;
  }

  private ArtifactSet buildTopLevelFiles(TreeLogger logger,
      ArtifactSet artifacts) {
    artifacts = new 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());
    return artifacts;
  }

  private ArtifactSet emitPermutationDescriptions(ArtifactSet artifacts) {
    artifacts = new 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));
    }

    return artifacts;
  }

  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;
  }
}
