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

import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Collections;
import java.util.Set;

/**
 * An abstract class that handles the details of launching a browser.
 */
public abstract class RunStyle {

  /**
   * The containing shell.
   */
  protected final JUnitShell shell;

  private int tries = 1;

  private Set<String> userAgents;

  /**
   * Constructor for RunStyle. Any subclass must provide a constructor with the
   * same signature since this will be how the RunStyle is created via
   * reflection.
   * 
   * @param shell the containing shell
   */
  public RunStyle(JUnitShell shell) {
    this.shell = shell;
  }

  /**
   * Tests whether the test was interrupted.
   * 
   * @return the interrupted hosts, or null if not interrupted
   */
  public String[] getInterruptedHosts() {
    return null;
  }

  /**
   * Get the host name of the local system to use in URLs. This method returns
   * the host address instead of the host name in case the test target cannot
   * resolve the host name.
   * 
   * @return the host name of the local system
   */
  public String getLocalHostName() {
    try {
      return InetAddress.getLocalHost().getHostAddress();
    } catch (UnknownHostException e) {
      throw new RuntimeException("Unable to determine my ip address", e);
    }
  }

  /**
   * Returns the platforms specific to this run style.
   */
  public Set<Platform> getPlatforms() {
    return Collections.emptySet();
  }

  /**
   * Returns user agents for this run style.
   *
   * @return the user agents, or {@code null} if unknown
   */
  public Set<String> getUserAgents() {
    return userAgents;
  }

  /**
   * Returns the number of times this test should be tried to run. A test
   * succeeds if it succeeds even once.
   * 
   * @return the number of attempts
   */
  public int getTries() {
    return tries;
  }

  /**
   * Initialize the runstyle with any supplied arguments, and return the number
   * of clients this runstyle controls.
   * 
   * @param args arguments passed in -runStyle option, null if none supplied
   * @return the number of clients, or -1 if initialization was unsuccessful
   */
  public abstract int initialize(String args);

  /**
   * Requests initial launch of the browser. This should only be called once per
   * instance of RunStyle.
   * 
   * @param moduleName the module to run
   * @throws UnableToCompleteException
   */
  public abstract void launchModule(String moduleName)
      throws UnableToCompleteException;

  /**
   * Sets the number of times a test should be tried -- it succeeds if any
   * attempt succeeds.
   * 
   * @param tries number of attempts
   */
  public void setTries(int tries) {
    this.tries = tries;
  }

  /**
   * Sets the associated user agents for this run style.
   */
  public void setUserAgents(Set<String> userAgents) {
    this.userAgents = userAgents;
  }

  /**
   * Setup this RunStyle for the selected mode.
   * 
   * @param logger TreeLogger to use for any messages
   * @param developmentMode true if we are running in development mode rather
   *          that web/production mode
   * @return false if we should abort processing due to an unsupported mode or
   *         an error setting up for that mode
   */
  public boolean setupMode(TreeLogger logger, boolean developmentMode) {
    return true;
  }

  /**
   * Whether the embedded server should ever generate resources. Development
   * mode needs this, but not with -noserver.
   * 
   * @return true if resources should be automatically generated by the server.
   */
  public boolean shouldAutoGenerateResources() {
    // TODO(spoon) does Production Mode get simpler if this is turned on?
    return true;
  }

  /**
   * Gets the shell logger.
   */
  protected TreeLogger getLogger() {
    return shell.getTopLogger();
  }
}
