/*
 * 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.dev.jjs.impl.gflow;

import com.google.gwt.dev.jjs.impl.gflow.TransformationFunction.Transformation;
import com.google.gwt.dev.util.Preconditions;

import java.util.ArrayList;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;

/**
 * Integrated analysis, which combines several other integrated analyses into
 * one. It does so be defining combined assumption, which is vector of original
 * assumptions, and applies each analysis to its own component.
 * 
 * If any analysis decides to rewrite the node, combined analysis returns
 * produced transformation. If more than one analyses decide to transform, the
 * first one wins.
 * 
 * @param <N> graph node type.
 * @param <E> graph edge type.
 * @param <T> graph transformer type.
 * @param <G> graph type.
 * 
 */
public class CombinedIntegratedAnalysis<N, E, T, G extends Graph<N, E, T>>
    implements
    IntegratedAnalysis<N, E, T, G, CombinedIntegratedAnalysis.CombinedAssumption> {

  /**
   * Combined assumption which holds vector of original assumptions.
   */
  public static class CombinedAssumption implements
      Assumption<CombinedAssumption> {
    
    private static class CopyOnWrite {
      private final int size;
      private CombinedAssumption assumption;
      private boolean copied = false;
      
      private CopyOnWrite(CombinedAssumption assumption, int size) {
        this.assumption = assumption;
        this.size = size;
      }

      public boolean isCopied() {
        return copied;
      }

      public void set(int slice, Assumption<?> assumption) {
        copyIfNeeded();
        this.assumption.set(slice, assumption);
      }

      public CombinedAssumption unwrap() {
        return assumption;
      }

      private void copyIfNeeded() {
        if (!copied) {
          copied = true;
          if (assumption == null) {
            assumption = new CombinedAssumption(size);
          } else {
            assumption = new CombinedAssumption(assumption);
          }
        }
      }
    }

    /**
     * Individual assumptions vector.
     */
    private final List<Assumption<?>> assumptions;

    public CombinedAssumption(CombinedAssumption assumption) {
      this.assumptions = new ArrayList<Assumption<?>>(assumption.assumptions);
    }

    public CombinedAssumption(int size) {
      this.assumptions = new ArrayList<Assumption<?>>(size);
      for (int i = 0; i < size; ++i) {
        this.assumptions.add(null);
      }
    }

    public CombinedAssumption(List<Assumption<?>> assumptions) {
      this.assumptions = assumptions;
    }

    @Override
    public boolean equals(Object obj) {
      if (this == obj) {
        return true;
      }
      if (obj == null) {
        return false;
      }

      CombinedAssumption other = (CombinedAssumption) obj;

      // We do not implement equals in our zipped lists. Do it here.
      if (other.assumptions.size() != assumptions.size()) {
        return false;
      }
      
      for (int i = 0; i < assumptions.size(); ++i) {
        Assumption<?> a1 = assumptions.get(i);
        Assumption<?> a2 = other.assumptions.get(i);
        if (a1 == null) {
          if (a1 != a2) {
            return false;
          }
        } else {
          if (a2 == null) {
            return false;
          }
          if (!a1.equals(a2)) {
            return false;
          }
        } 
      }
      
      return true;
    }

    @Override
    public int hashCode() {
      final int prime = 31;
      int result = 1;
      result = prime * result
          + ((assumptions == null) ? 0 : assumptions.hashCode());
      return result;
    }

    /**
     * Joins combined assumption by joining all individual components.
     */
    @SuppressWarnings("unchecked")
    public CombinedAssumption join(CombinedAssumption value) {
      if (value == null) {
        return this;
      }
      Preconditions.checkArgument(value.assumptions.size() == 
        assumptions.size());
      
      List<Assumption<?>> newAssumptions = new ArrayList<Assumption<?>>();
      for (int i = 0; i < assumptions.size(); ++i) {
        Assumption a1 = assumptions.get(i);
        Assumption a2 = value.assumptions.get(i);
        newAssumptions.add(AssumptionUtil.join(a1, a2));
      }

      return new CombinedAssumption(newAssumptions);
    }

    @Override
    public String toString() {
      return assumptions.toString();
    }

    /**
     * Gets nth assumption component.
     */
    private Assumption<?> get(int n) {
      return assumptions.get(n);
    }

    private void set(int slice, Assumption<?> assumption) {
      assumptions.set(slice, assumption);
    }
  }

  /**
   * Combined integrated flow function.
   */
  private final class CombinedIntegratedFlowFunction implements
      IntegratedFlowFunction<N, E, T, G, CombinedAssumption> {
    @SuppressWarnings("unchecked")
    public Transformation interpretOrReplace(final N node, final G graph,
        final AssumptionMap<E, CombinedAssumption> assumptionMap) {
      
      final Map<E, CombinedAssumption.CopyOnWrite> newAssumptions = new IdentityHashMap<E, CombinedAssumption.CopyOnWrite>();
      
      final int size = functions.size();
      for (int i = 0; i < size; ++i) {
        final int slice = i;
        IntegratedFlowFunction function = functions.get(i);
        
        Transformation transformation = 
          function.interpretOrReplace(node, graph, 
              new AssumptionMap() {
                public Assumption getAssumption(Object edge) {
                  CombinedAssumption combinedAssumption = assumptionMap.getAssumption((E) edge);
                  if (combinedAssumption == null) {
                    return null;
                  }
                  return combinedAssumption.get(slice);
                }

                public void setAssumption(Object edge, Assumption assumption) {
                  CombinedAssumption.CopyOnWrite newAssumption = newAssumptions.get(edge);
                  if (newAssumption == null) {
                    newAssumption = new CombinedAssumption.CopyOnWrite(assumptionMap.getAssumption((E) edge), size);
                    newAssumptions.put((E) edge, newAssumption);
                  }
                  newAssumption.set(slice, assumption);
                }

                @Override
                public String toString() {
                  return AssumptionUtil.toString(graph.getInEdges(node), 
                      graph.getOutEdges(node), this);
                }
              });
        
        if (transformation != null) {
          return transformation;
        }
      }

      for (E e : newAssumptions.keySet()) {
        CombinedAssumption.CopyOnWrite newAssumption = newAssumptions.get(e);
        if (newAssumption.isCopied()) {
          assumptionMap.setAssumption(e, newAssumption.unwrap());
        }
      }
      
      return null;
    }
  }

  /**
   * Factory method. 
   */
  public static <N, E, T, G extends Graph<N, E, T>> 
  CombinedIntegratedAnalysis<N, E, T, G> createAnalysis() {
    return new CombinedIntegratedAnalysis<N, E, T, G>();
  }
  /**
   * Individual analyses.
   */
  List<IntegratedAnalysis<N, E, T, G, ?>> analyses = 
    new ArrayList<IntegratedAnalysis<N, E, T, G, ?>>();

  /**
   * Their flow functions.
   */
  List<IntegratedFlowFunction<N, E, T, G, ?>> functions = 
    new ArrayList<IntegratedFlowFunction<N, E, T, G, ?>>();

  /**
   * Adds analysis to the combined one.
   */
  public void addAnalysis(IntegratedAnalysis<N, E, T, G, ?> analysis) {
    analyses.add(analysis);
    functions.add(analysis.getIntegratedFlowFunction());
  }

  public IntegratedFlowFunction<N, E, T, G, CombinedAssumption> 
  getIntegratedFlowFunction() {
    return new CombinedIntegratedFlowFunction();
  }
  
  @SuppressWarnings("unchecked")
  public void setInitialGraphAssumptions(G graph,
      final AssumptionMap<E, CombinedAssumption> assumptionMap) {
    for (int i = 0; i < functions.size(); ++i) {
      final int slice = i;
      IntegratedAnalysis<N, E, T, G, ?> analysis = analyses.get(slice);
      analysis.setInitialGraphAssumptions(graph, new AssumptionMap() {
        public Assumption getAssumption(Object edge) {
          throw new UnsupportedOperationException();
        }

        public void setAssumption(Object edge,Assumption assumption) {
          CombinedAssumption combinedAssumption = assumptionMap.getAssumption((E) edge);
          if (combinedAssumption == null) {
            combinedAssumption = new CombinedAssumption(functions.size());
            combinedAssumption.set(slice, assumption);
            assumptionMap.setAssumption((E) edge, combinedAssumption);
          } else {
            combinedAssumption.set(slice, assumption);
          }
        }
      });
    }
  }
}
