/*
 * 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.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() {
    return "localhost";
  }

  /**
   * 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();
  }
}
