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

import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.dev.jdt.RebindPermutationOracle;
import com.google.gwt.dev.jjs.InternalCompilerException;
import com.google.gwt.dev.jjs.ast.Context;
import com.google.gwt.dev.jjs.ast.HasEnclosingType;
import com.google.gwt.dev.jjs.ast.HasName;
import com.google.gwt.dev.jjs.ast.JClassLiteral;
import com.google.gwt.dev.jjs.ast.JClassType;
import com.google.gwt.dev.jjs.ast.JDeclaredType;
import com.google.gwt.dev.jjs.ast.JExpression;
import com.google.gwt.dev.jjs.ast.JGwtCreate;
import com.google.gwt.dev.jjs.ast.JMethod;
import com.google.gwt.dev.jjs.ast.JMethodCall;
import com.google.gwt.dev.jjs.ast.JModVisitor;
import com.google.gwt.dev.jjs.ast.JNameOf;
import com.google.gwt.dev.jjs.ast.JNullLiteral;
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.dev.jjs.ast.JReferenceType;
import com.google.gwt.dev.jjs.ast.JStringLiteral;
import com.google.gwt.dev.util.JsniRef;
import com.google.gwt.dev.util.log.speedtracer.CompilerEventType;
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;

import java.util.ArrayList;
import java.util.List;

/**
 * Replaces any "GWT.create()" calls with a special node.
 */
public class ReplaceRebinds {

  private class RebindVisitor extends JModVisitor {

    private JDeclaredType currentClass;
    private final JMethod nameOfMethod;
    private final JMethod rebindCreateMethod;

    public RebindVisitor(JMethod nameOfMethod, JMethod rebindCreateMethod) {
      this.nameOfMethod = nameOfMethod;
      this.rebindCreateMethod = rebindCreateMethod;
    }

    @Override
    public void endVisit(JMethodCall x, Context ctx) {
      JMethod method = x.getTarget();
      if (method == nameOfMethod) {
        replaceImplNameOf(x, ctx);

      } else if (method == rebindCreateMethod) {
        replaceGwtCreate(x, ctx);
      }
    }

    @Override
    public boolean visit(JMethod x, Context ctx) {
      currentClass = x.getEnclosingType();
      return true;
    }

    private void replaceGwtCreate(JMethodCall x, Context ctx) {
      assert (x.getArgs().size() == 1);
      JExpression arg = x.getArgs().get(0);
      assert (arg instanceof JClassLiteral);
      JClassLiteral classLiteral = (JClassLiteral) arg;
      JReferenceType sourceType = (JReferenceType) classLiteral.getRefType();
      List<JClassType> allRebindResults = getAllPossibleRebindResults(sourceType);
      JGwtCreate gwtCreate = new JGwtCreate(x.getSourceInfo(), sourceType,
          allRebindResults, program.getTypeJavaLangObject(), currentClass);
      if (allRebindResults.size() == 1) {
        // Just replace with the instantiation expression.
        ctx.replaceMe(gwtCreate.getInstantiationExpressions().get(0));
      } else {
        ctx.replaceMe(gwtCreate);
      }
    }

    private void replaceImplNameOf(JMethodCall x, Context ctx) {
      JExpression arg0 = x.getArgs().get(0);
      assert arg0 instanceof JStringLiteral;
      JStringLiteral stringLiteral = (JStringLiteral) arg0;
      String stringValue = stringLiteral.getValue();

      HasName named = null;

      JDeclaredType refType;
      JsniRef ref = JsniRef.parse(stringValue);

      if (ref != null) {
        final List<String> errors = new ArrayList<String>();
        HasEnclosingType node = JsniRefLookup.findJsniRefTarget(ref, program,
            new JsniRefLookup.ErrorReporter() {
              public void reportError(String error) {
                errors.add(error);
              }
            });

        if (!errors.isEmpty()) {
          for (String error : errors) {
            logger.log(TreeLogger.ERROR, error);
          }
        }

        if (node instanceof HasName) {
          named = (HasName) node;
        }

      } else {
        // See if it's just @foo.Bar, which would result in the class seed
        refType = program.getFromTypeMap(stringValue.charAt(0) == '@'
            ? stringValue.substring(1) : stringValue);
        if (refType != null) {
          named = refType;
        }
      }

      if (named == null) {
        // Not found, must be null
        ctx.replaceMe(JNullLiteral.INSTANCE);
      } else {
        ctx.replaceMe(new JNameOf(x.getSourceInfo(), stringLiteral.getType(),
            named));
      }
    }
  }

  public static boolean exec(TreeLogger logger, JProgram program,
      RebindPermutationOracle rpo) {
    Event replaceRebindsEvent = SpeedTracerLogger.start(CompilerEventType.REPLACE_REBINDS);
    boolean didChange = new ReplaceRebinds(logger, program, rpo).execImpl();
    replaceRebindsEvent.end();
    return didChange;
  }

  private final TreeLogger logger;
  private final JProgram program;
  private final RebindPermutationOracle rpo;

  private ReplaceRebinds(TreeLogger logger, JProgram program,
      RebindPermutationOracle rpo) {
    this.logger = logger;
    this.program = program;
    this.rpo = rpo;
  }

  protected List<JClassType> getAllPossibleRebindResults(JReferenceType type) {
    // Rebinds are always on a source type name.
    String reqType = type.getName().replace('$', '.');
    String[] answers;
    try {
      answers = rpo.getAllPossibleRebindAnswers(logger, reqType);
    } catch (UnableToCompleteException e) {
      // Should never happen.
      throw new InternalCompilerException(
          "Unexpected failure to get possible rebind answers for '" + reqType
              + "'");
    }
    List<JClassType> rebindAnswers = new ArrayList<JClassType>();
    for (String answer : answers) {
      JReferenceType result = program.getFromTypeMap(answer);
      assert (result != null);
      rebindAnswers.add((JClassType) result);
    }
    assert rebindAnswers.size() > 0;
    return rebindAnswers;
  }

  private boolean execImpl() {
    RebindVisitor rebinder = new RebindVisitor(
        program.getIndexedMethod("Impl.getNameOf"),
        program.getIndexedMethod("GWT.create"));
    rebinder.accept(program);
    return rebinder.didChange();
  }

}
