/*
 * Copyright 2008 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.copy;

import com.google.gwt.dev.jjs.ast.HasName;
import com.google.gwt.dev.jjs.ast.JVariable;
import com.google.gwt.dev.jjs.impl.gflow.Assumption;
import com.google.gwt.dev.util.Preconditions;
import com.google.gwt.dev.util.collect.Lists;

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

/**
 * Assumption class for CopyAnalysis.
 */
public class CopyAssumption implements Assumption<CopyAssumption> {
  /**
   * Top value for copy analysis. Means nothing is the copy of anything.
   */
  public static final CopyAssumption TOP = new CopyAssumption();
  
  /**
   * Updates the assumption by copying it on first write.
   */
  public static class Updater {
    private CopyAssumption assumption;
    private boolean copied = false;
    
    public Updater(CopyAssumption assumption) {
      this.assumption = assumption;
    }

    public void addCopy(JVariable original, JVariable targetVariable) {
      Preconditions.checkArgument(original != targetVariable, 
          "Variable is a copy of itself: %s", original);
      copyIfNeeded();
      assumption.addCopy(original, targetVariable);
    }

    public JVariable getMostOriginal(JVariable variable) {
      for (int i = 0; i < 10000; ++i) {
        JVariable original = getOriginal(variable);
        if (original == null) {
          return variable;
        }
        
        variable = original;
      }
      // We shouldn't have cycle if we always call getMostOriginal() before 
      // invoking addCopy.
      // This is a rudimentary cycle detection :)
      throw new IllegalStateException("Possible cycle detected for: variable");
    }

    public JVariable getOriginal(JVariable variable) {
      if (assumption == null || assumption == TOP) {
        return null;
      }
      
      return assumption.getOriginal(variable);
    }

    public void kill(JVariable targetVariable) {
      if (assumption == TOP) {
        return;
      }
      copyIfNeeded();
      assumption.kill(targetVariable);
    }

    public CopyAssumption unwrap() {
      if (assumption == TOP) {
        return assumption;
      }
      if (assumption != null && assumption.copyToOriginal.isEmpty()) {
        return null;
      }
      return assumption;
    }

    private void copyIfNeeded() {
      if (!copied) {
        assumption = new CopyAssumption(assumption);
        copied = true;
      }
    }
  }
    
  /**
   * Map from copies to original values.
   */
  private final Map<JVariable, JVariable> copyToOriginal;
  
  public CopyAssumption() {
    copyToOriginal = new IdentityHashMap<JVariable, JVariable>();
  }

  public CopyAssumption(CopyAssumption result) {
    if (result != null) {
      copyToOriginal = new IdentityHashMap<JVariable, JVariable>(result.copyToOriginal);
    } else {
      copyToOriginal = new IdentityHashMap<JVariable, JVariable>();
    }
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }
    if (obj == null) {
      return false;
    }
    if (getClass() != obj.getClass()) {
      return false;
    }
    CopyAssumption other = (CopyAssumption) obj;
    return other.copyToOriginal.equals(copyToOriginal);
  }

  public JVariable getOriginal(JVariable v) {
    return copyToOriginal.get(v);
  }

  @Override
  public int hashCode() {
    return copyToOriginal.hashCode();
  }

  public CopyAssumption join(CopyAssumption value) {
    if (value == null) {
      return this;
    }
    
    if (this == TOP || value == TOP) {
      return TOP;
    }
    
    if (value.copyToOriginal.isEmpty() || copyToOriginal.isEmpty()) {
      return null;
    }
    
    CopyAssumption result = new CopyAssumption();
    
    for (JVariable v : copyToOriginal.keySet()) {
      JVariable original = copyToOriginal.get(v);
      if (original == value.copyToOriginal.get(v)) {
        result.copyToOriginal.put(v, original);
      } else {
        result.copyToOriginal.put(v, null);
      }
    }
    
    return result;
  }

  @Override
  public String toString() {
    if (this == TOP) {
      return "T";
    }
    
    StringBuffer result = new StringBuffer();
    
    result.append("{");
    List<JVariable> variables = new ArrayList<JVariable>(
        copyToOriginal.keySet());
    HasName.Util.sortByName(variables);
    for (JVariable variable : variables) {
      if (result.length() > 1) {
        result.append(", ");
      }
      result.append(variable.getName());
      result.append(" = ");
      if (copyToOriginal.get(variable) == null) {
        result.append("T");
      } else {
        result.append(copyToOriginal.get(variable).getName());
      }
    }
    result.append("}");
    
    return result.toString();  
  }

  private void addCopy(JVariable original, JVariable copy) {
    Preconditions.checkArgument(this != TOP);
    copyToOriginal.put(copy, original);
  }

  private void kill(JVariable variable) {
    copyToOriginal.put(variable, null);
    
    for (JVariable v : Lists.create(copyToOriginal.keySet())) {
      JVariable original = copyToOriginal.get(v);
      if (original == variable) {
        copyToOriginal.put(v, null);
      }
    }
  }
}
