/*
 * Copyright 2014 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.codeserver;

import com.google.gwt.dev.cfg.ModuleDef;
import com.google.gwt.dev.cfg.ModuleDefSchema;
import com.google.gwt.thirdparty.guava.common.base.Preconditions;
import com.google.gwt.thirdparty.guava.common.collect.ImmutableList;
import com.google.gwt.thirdparty.guava.common.collect.ImmutableMap;
import com.google.gwt.thirdparty.guava.common.collect.ImmutableSortedMap;

import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.regex.Pattern;

/**
 * The status of a compile job submitted to Super Dev Mode.
 *
 * <p>JobEvent objects are deeply immutable, though they describe a Job that changes.
 */
public final class JobEvent {
  private static final Pattern VALID_TAG = Pattern.compile("\\S{1,100}");

  private final String jobId;

  private final String inputModuleName;
  private final ImmutableSortedMap<String, String> bindings;
  private final Status status;
  private final String message;

  private final String outputModuleName;
  private final CompileDir compileDir;
  private final CompileStrategy compileStrategy;
  private final ImmutableList<String> arguments;
  private final ImmutableList<String> tags;

  private JobEvent(Builder builder) {
    this.jobId = Preconditions.checkNotNull(builder.jobId);
    this.inputModuleName = Preconditions.checkNotNull(builder.inputModuleName);
    this.bindings = ImmutableSortedMap.copyOf(builder.bindings);
    this.status = Preconditions.checkNotNull(builder.status);
    this.message = builder.message == null ? status.defaultMessage : builder.message;

    // The following fields may be null.
    this.outputModuleName = builder.outputModuleName;
    this.compileDir = builder.compileDir;
    this.compileStrategy = builder.compileStrategy;
    this.arguments = ImmutableList.copyOf(builder.args);
    this.tags = ImmutableList.copyOf(builder.tags);

    // Any new fields added should allow nulls for backward compatibility.
  }

  /**
   * The id of the job being compiled. Unique within the same CodeServer process.
   * This should be considered an opaque string.
   */
  public String getJobId() {
    return jobId;
  }

  /**
   * The module name sent to the GWT compiler to start the compile.
   */
  public String getInputModuleName() {
    return inputModuleName;
  }

  /**
   * The binding properties sent to the GWT compiler.
   */
  public SortedMap<String, String> getBindings() {
    // Can't return ImmutableSortedMap here because it's repackaged and this is a public API.
    return bindings;
  }

  /**
   * The last reported status of the job.
   */
  public Status getStatus() {
    return status;
  }

  /**
   * Returns a line of text describing the job's current status.
   */
  public String getMessage() {
    return message;
  }

  /**
   * Returns the module name used for the output of the GWT compiler, or null if not available.
   * (This name is used for the name of the module directory, the nocache.js file, and in all
   * JavaScript generated by the GWT compiler.)
   * Only available for completed, successful compiles.
   */
  public String getOutputModuleName() {
    return outputModuleName;
  }

  /**
   * Returns the directory where the GWT module is being compiled, or null if not available.
   * (Not available for jobs that are WAITING.)
   */
  public CompileDir getCompileDir() {
    return compileDir;
  }

  /**
   * Returns the strategy used to perform the compile or null if not available.
   * (Normally available for finished compiles.)
   */
  public CompileStrategy getCompileStrategy() {
    return compileStrategy;
  }

  /**
   * The arguments passed to Super Dev Mode at startup, or null if not available.
   */
  public ImmutableList<String> getArguments() {
    return arguments;
  }

  /**
   * User-defined tags associated with this job. (Not null but may be empty.)
   */
  public ImmutableList<String> getTags() { return tags; }

  /**
   * If all the given tags are valid, returns a list containing the tags.
   * @throws java.lang.IllegalArgumentException if any tag is invalid.
   */
  static ImmutableList<String> checkTags(Iterable<String> tags) {
    ImmutableList.Builder<String> builder = ImmutableList.builder();
    for (String tag : tags) {
      if (!isValidTag(tag)) {
        throw new IllegalArgumentException("invalid tag: " + tag);
      }
      builder.add(tag);
    }
    return builder.build();
  }

  /**
   * Returns true if the tag is valid.
   * Tags must not be null, contain whitespace, or be more than 100 characters.
   */
  private static boolean isValidTag(String candidate) {
    return candidate != null && VALID_TAG.matcher(candidate).matches();
  }

  /**
   * Defines the lifecycle of a job.
   */
  public enum Status {
    WAITING("waiting", "Waiting for the compiler to start"),
    COMPILING("compiling", "Compiling"),
    SERVING("serving", "Compiled output is ready"),
    GONE("gone", "Compiled output is no longer available"),
    ERROR("error", "Compile failed with an error");

    final String jsonName;
    final String defaultMessage;

    Status(String jsonName, String defaultMessage) {
      this.jsonName = jsonName;
      this.defaultMessage = defaultMessage;
    }
  }

  /**
   * The approach taken to do the compile.
   */
  public enum CompileStrategy {
    FULL("full"), // Compiled all the source.
    INCREMENTAL("incremental"), // Only recompiled the source files that changed.
    SKIPPED("skipped"); // Did not compile anything since nothing changed

    final String jsonName;

    CompileStrategy(String jsonName) {
      this.jsonName = jsonName;
    }

    /**
     * The string to use for serialization.
     */
    public String getJsonName() {
      return jsonName;
    }
  }

  /**
   * Creates a JobEvent.
   * This is public to allow external tests of code that implements {@link JobChangeListener}.
   * Normally all JobEvents are created in the code server.
   */
  public static class Builder {
    private String jobId;

    private String inputModuleName;
    private Map<String, String> bindings = ImmutableMap.of();
    private Status status;
    private String message;
    private CompileDir compileDir;
    private CompileStrategy compileStrategy;
    private List<String> args = ImmutableList.of();
    private List<String> tags = ImmutableList.of();
    private String outputModuleName;

    /**
     * A unique id for this job. Required.
     */
    public void setJobId(String jobId) {
      Preconditions.checkArgument(Job.isValidJobId(jobId), "invalid job id: " + jobId);
      this.jobId = jobId;
    }

    /**
     * The name of the module as passed to the compiler. Required.
     */
    public void setInputModuleName(String inputModuleName) {
      Preconditions.checkArgument(ModuleDef.isValidModuleName(inputModuleName),
          "invalid module name: " + jobId);
      this.inputModuleName = inputModuleName;
    }

    /**
     * The bindings passed to the compiler.
     * Optional, but may not be null. (Defaults to the empty map.)
     */
    public void setBindings(Map<String, String> bindings) {
      for (String name : bindings.keySet()) {
        if (!ModuleDefSchema.isValidPropertyName(name)) {
          throw new IllegalArgumentException("invalid property name: " + name);
        }
      }
      this.bindings = bindings;
    }

    /**
     * The job's current status. Required.
     */
    public void setStatus(Status status) {
      this.status = status;
    }

    /**
     * A message to describing the job's current state.
     * It should be a single line of text.
     * Optional. If null, a default message will be used.
     */
    public void setMessage(String message) {
      if (message != null) {
        Preconditions.checkArgument(!message.contains("\n"),
            "JobEvent messages should be a single line of text");
      }
      this.message = message;
    }

    /**
     * The module name that the compiler returned (after rename).
     */
    public void setOutputModuleName(String name) {
      this.outputModuleName = name;
    }

    /**
     * The directory where the GWT compiler will write its output.
     * Optional. (Not available until the compile starts.)
     */
    public void setCompileDir(CompileDir compileDir) {
      this.compileDir = compileDir;
    }

    /**
     * The strategy used to perform the compile.
     * Optional.
     */
    public void setCompileStrategy(CompileStrategy compileStrategy) {
      this.compileStrategy = compileStrategy;
    }

    /**
     * The arguments passed to {@link Options#parseArgs} at startup.
     * Optional but may not be null. If not set, defaults to the empty list.
     */
    public void setArguments(List<String> args) {
      this.args = Preconditions.checkNotNull(args);
    }

    /**
     * User-defined tags passed to {@link Options#addTags}.
     * Optional but may not be null. If not set, defaults to the empty list.
     */
    public void setTags(Iterable<String> tags) {
      this.tags = checkTags(tags);
    }

    public JobEvent build() {
      return new JobEvent(this);
    }
  }
}
