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

import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.dev.jjs.ast.Context;
import com.google.gwt.dev.jjs.ast.JClassType;
import com.google.gwt.dev.jjs.ast.JConstructor;
import com.google.gwt.dev.jjs.ast.JDeclaredType;
import com.google.gwt.dev.jjs.ast.JExpression;
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.JNewInstance;
import com.google.gwt.dev.jjs.ast.JNullLiteral;
import com.google.gwt.dev.jjs.ast.JParameter;
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.dev.jjs.ast.JVisitor;

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

/**
 * Performs optimizations on Enums.
 */
public class EnumNameObfuscator {

  private static class EnumNameCallChecker extends JVisitor {

    private final JDeclaredType classType;
    private final JMethod enumNameMethod;
    private final JMethod enumToStringMethod;
    private final JDeclaredType enumType;
    private final JMethod enumValueOfMethod;
    private final TreeLogger logger;
    private final List<String> blacklistedEnums;
    private final JDeclaredType stringType;

    public EnumNameCallChecker(JProgram jprogram, TreeLogger logger,
        List<String> blacklistedEnums) {
      this.logger = logger;
      this.blacklistedEnums = blacklistedEnums;
      this.enumNameMethod = jprogram.getIndexedMethod("Enum.name");
      this.enumToStringMethod = jprogram.getIndexedMethod("Enum.toString");
      this.classType = jprogram.getIndexedType("Class");
      this.enumType = jprogram.getIndexedType("Enum");
      this.stringType = jprogram.getIndexedType("String");

      /*
       * Find the correct version of enumValueOfMethod.
       *
       * Note: it doesn't work to check against a ref returned by
       * jprogram.getIndexedMethod("Enum.valueOf"), since there are 2 different
       * versions of Enum.valueOf in our jre emulation library, and the indexed
       * ref won't reliably flag the public instance, which is the one we want
       * here (i.e. Enum.valueOf(Class<T>,String)). The other version is
       * protected, but is called by the generated constructors for sub-classes
       * of Enum, and we don't want to warn for those cases.
       */
      JMethod foundMethod = null;
      List<JMethod> enumMethods = enumType.getMethods();
      for (JMethod enumMethod : enumMethods) {
        if ("valueOf".equals(enumMethod.getName())) {
          List<JParameter> jParameters = enumMethod.getParams();
          if (jParameters.size() == 2 && jParameters.get(0).getType() == classType
              && jParameters.get(1).getType() == stringType) {
            foundMethod = enumMethod;
            break;
          }
        }
      }
      this.enumValueOfMethod = foundMethod;
    }

    @Override
    public void endVisit(JMethodCall x, Context ctx) {
      JMethod target = x.getTarget();
      JDeclaredType type = target.getEnclosingType();

      if (type instanceof JClassType) {
        JClassType cType = (JClassType) type;
        if (typeInBlacklist(blacklistedEnums, cType)) {
          return;
        }
        if (target == enumNameMethod || target == enumToStringMethod || target == enumValueOfMethod) {
          warn(x);
        } else if (cType.isEnumOrSubclass() != null) {
          if ("valueOf".equals(target.getName())) {
            /*
             * Check for calls to the auto-generated
             * EnumSubType.valueOf(String). Note, the check of the signature for
             * the single String arg version is to avoid flagging user-defined
             * overloaded versions of the method, which are presumably ok.
             */
            List<JParameter> jParameters = target.getParams();
            if (jParameters.size() == 1 && jParameters.get(0).getType() == stringType) {
              warn(x);
            }
          }
        }
      }
    }

    @Override
    public boolean visit(JClassType x, Context ctx) {
      if (x == enumType) {
        // don't traverse into Enum class itself, don't warn on internal method
        // calls
        return false;
      }
      return true;
    }

    private void warn(JMethodCall x) {
      /*
       * TODO: add a way to suppress warning with annotation if you know what
       * you're doing.
       */
      logger.log(TreeLogger.WARN, "Call to Enum method " + x.getTarget().getName()
          + " when enum obfuscation is enabled:  " + x.getSourceInfo().getFileName() + ":"
          + x.getSourceInfo().getStartLine());
    }
  }

  private static class EnumNameReplacer extends JModVisitor {

    private final JProgram jprogram;
    private final JMethod makeEnumName;
    private List<String> blacklistedEnums;
    private boolean closureMode;
    private final TreeLogger logger;

    public EnumNameReplacer(JProgram jprogram, TreeLogger logger,
        List<String> blacklistedEnums, boolean closureMode) {
      this.logger = logger;
      this.jprogram = jprogram;
      this.blacklistedEnums = blacklistedEnums;
      this.closureMode = closureMode;
      this.makeEnumName = jprogram.getIndexedMethod("Util.makeEnumName");
    }

    public void exec() {
      accept(jprogram);
    }

    @Override public boolean visit(JClassType x, Context ctx) {
      if (x.isEnumOrSubclass() == null || typeInBlacklist(blacklistedEnums, x)) {
        return false;
      }
      trace(x);
      return true;
    }

    @Override public void endVisit(JNewInstance x, Context ctx) {
      JConstructor target = x.getTarget();
      JClassType enclosingType = target.getEnclosingType();
      if (enclosingType.isEnumOrSubclass() != null) {
        if (!typeInBlacklist(blacklistedEnums, enclosingType)) {
          JNewInstance newEnum = new JNewInstance(x);
          // replace first argument with null
          List<JExpression> args = new ArrayList<JExpression>(x.getArgs());
          if (closureMode) {
            JMethodCall makeEnum = new JMethodCall(x.getSourceInfo(), null, makeEnumName, args.get(0));
            args.set(0, makeEnum);
          } else {
            args.set(0, JNullLiteral.INSTANCE);
          }
          newEnum.addArgs(args);
          ctx.replaceMe(newEnum);
        }
      }
    }

    private void trace(JClassType x) {
      if (logger.isLoggable(TreeLogger.TRACE)) {
        logger.log(TreeLogger.TRACE,
            "Obfuscating enum " + x
            + x.getSourceInfo().getFileName() + ":"
            + x.getSourceInfo().getStartLine());
      }
    }
  }

  private static boolean typeInBlacklist(List<String> blacklistedEnums, JClassType cType) {
    return blacklistedEnums.contains(cType.getName().replace('$', '.'));
  }

  public static void exec(JProgram jprogram, TreeLogger logger,
      List<String> blacklistedEnums, boolean closureMode) {
    new EnumNameCallChecker(jprogram, logger, blacklistedEnums).accept(jprogram);
    new EnumNameReplacer(jprogram, logger, blacklistedEnums, closureMode).exec();
  }
}
