/*
 * 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.UnableToCompleteException;
import com.google.gwt.dev.jjs.ast.JDeclaredType;
import com.google.gwt.dev.jjs.ast.JField;
import com.google.gwt.dev.jjs.ast.JMethod;
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.dev.util.Preconditions;
import com.google.gwt.dev.util.Strings;

import java.util.regex.Pattern;

/**
 * Test case for testing Jjs optimizers. Adds a convenient Result class.
 */
public abstract class OptimizerTestBase extends JJSTestBase {
  protected boolean runDeadCodeElimination = false;
  
  protected final class Result {
    private final String returnType;
    private final String originalCode;
    private final boolean madeChages;
    private final JProgram optimizedProgram;
    private final String methodName;

    public Result(JProgram optimizedProgram, String returnType, 
        String methodName, String originalCode, boolean madeChages) {
      this.optimizedProgram = optimizedProgram;
      this.returnType = returnType;
      this.methodName = methodName;
      this.originalCode = originalCode;
      this.madeChages = madeChages;
    }

    public void into(String... expected) throws UnableToCompleteException {
      // We can't compile expected code into non-main method.
      Preconditions.checkState(methodName.equals(MAIN_METHOD_NAME));
      JProgram program = compileSnippet(returnType,
          Strings.join(expected, "\n"));
      String expectedSource = 
        OptimizerTestBase.findMethod(program, methodName).getBody().toSource();
      String actualSource = 
        OptimizerTestBase.findMethod(optimizedProgram, methodName).
        getBody().toSource();
      assertEquals(originalCode, expectedSource, actualSource);
    }

    public void intoString(String... expected) {
      String expectedSource = Strings.join(expected, "\n");
      String actualSource = 
        OptimizerTestBase.findMethod(optimizedProgram, methodName).
        getBody().toSource();

      // Trim surrounding {} and unindent body once
      assertTrue(actualSource.startsWith("{"));
      assertTrue(actualSource.endsWith("}"));
      actualSource = actualSource.substring(1, actualSource.length() - 2).trim();
      actualSource = Pattern.compile("^  ", Pattern.MULTILINE).
          matcher(actualSource).replaceAll("");
      
      assertEquals(originalCode, expectedSource, actualSource);
    }

    public void noChange() {
      assertFalse(madeChages);
    }

    public JMethod findMethod(String methodName) {
      return OptimizerTestBase.findMethod(optimizedProgram, methodName);
    }

    public JField findField(String fieldName) {
      return OptimizerTestBase.findField(optimizedProgram, 
          "EntryPoint." + fieldName);
    }

    public JDeclaredType findClass(String className) {
      return OptimizerTestBase.findType(optimizedProgram, className);
    }
  }

  protected final Result optimize(final String returnType, 
      final String... codeSnippet) throws UnableToCompleteException {
    return optimizeMethod(MAIN_METHOD_NAME, returnType, codeSnippet);
  }

  protected final Result optimizeMethod(final String methodName,
      final String mainMethodReturnType, final String... mainMethodSnippet)
      throws UnableToCompleteException {
    String snippet = Strings.join(mainMethodSnippet, "\n");
    JProgram program = compileSnippet(mainMethodReturnType, snippet);
    JMethod method = findMethod(program, methodName);
    boolean madeChanges = optimizeMethod(program, method);
    if (madeChanges && runDeadCodeElimination) {
      DeadCodeElimination.exec(program);
    }
    return new Result(program, mainMethodReturnType, methodName, snippet, madeChanges);
  }

  protected abstract boolean optimizeMethod(JProgram program, JMethod method);
}
