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

import com.google.gwt.dev.cfg.BindingProperty;
import com.google.gwt.dev.cfg.ModuleDef;
import com.google.gwt.dev.cfg.Properties;
import com.google.gwt.dev.util.Util;
import com.google.gwt.junit.JUnitShell.Strategy;
import com.google.gwt.junit.client.WithProperties;
import com.google.gwt.junit.client.WithProperties.Property;

import junit.framework.TestCase;

import java.lang.reflect.Method;
import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;

/**
 * A {@link JUnitShell.Strategy} that will alter the module the tests are run
 * in by defining module properties as requested by annotations on the tests.
 */
public class PropertyDefiningStrategy implements Strategy {
  private TestCase testCase;
  private Set<Property> properties;

  public PropertyDefiningStrategy(TestCase testCase) {
    this.testCase = testCase;
  }

  @Override
  public String getSyntheticModuleExtension() {
    String extension = "JUnit";
    computePropertiesMap();
    if (properties.size() > 0) {
      StringBuilder sb = new StringBuilder();
      for (Property property : properties) {
        sb.append(".").append(property.name()).append(
            "_").append(property.value());
      }
      extension += sb.toString();
    }
    return extension;
  }

  @Override
  public void processModule(ModuleDef module) {
    computePropertiesMap();
    if (properties.size() > 0) {
      Properties props = module.getProperties();
      for (Property property : properties) {
        BindingProperty binding = props.createBinding(property.name());
        if (!binding.isDefinedValue(property.value())) {
          binding.addTargetLibraryDefinedValue(binding.getRootCondition(), property.value());
        }
        binding.setValues(
            binding.getRootCondition(), property.value());
      }
    }
  }

  private Property checkProperty(Property property) {
    String[] tokens = (property.name() + ". ").split("\\.");
    for (int i = 0; i < tokens.length - 1; i++) {
      if (!Util.isValidJavaIdent(tokens[i])) {
        throw new AssertionError(
            "Property name invalid: " + property.name());
      }
    }

    if (!Util.isValidJavaIdent(property.value())) {
      throw new AssertionError(
          "Property value invalid: " + property.value());
    }

    return property;
  }

  private void computePropertiesMap() {
    if (properties == null) {
      Set<Property> props = new TreeSet<Property>(
          new Comparator<Property>() {
        public int compare(Property p1, Property p2) {
          int r = p1.name().compareTo(p2.name());
          if (r == 0) {
            r = p1.value().compareTo(p2.value());
          }
          return r;
        }
      });
      try {
        String name = testCase.getName();
        if (name != null) {
          Method testMethod = testCase.getClass().getMethod(testCase.getName());
          if (testMethod.isAnnotationPresent(WithProperties.class)) {
            WithProperties annotation =
              testMethod.getAnnotation(WithProperties.class);
            for (Property property : annotation.value()) {
              props.add(checkProperty(property));
            }
          }
        }
      } catch (SecurityException e) {
        // should not happen
        e.printStackTrace();
      } catch (NoSuchMethodException e) {
        // should not happen
        e.printStackTrace();
      }
      properties = props;
    }
  }
}
