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

import com.google.gwt.dev.util.Preconditions;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

/**
 * A representation of a parsed (X)HTML template.
 *
 * <p>A parsed template is represented as a sequence of template chunks.
 *
 * <p>A chunk may correspond to a literal string or to a formal template
 * parameter.
 *
 * <p>Parameter chunks have an attribute that refers to the index of the
 * corresponding template method parameter, as well as an attribute that
 * represents the HTML context the template parameter appeared in.
 */
final class ParsedHtmlTemplate {

  /**
   * A representation of the context of a point within a HTML document. A
   * context consists of a type (such as "plain text", "attribute"), as well as
   * a HTML tag and attribute name where applicable.
   */
  static final class HtmlContext {
    /**
     * The possible types of HTML context.
     */
    // TODO(xtof): Possibly add support for other contexts, such as style.
    static enum Type {
      /**
       * The undefined HTML context. Contexts of this type are meant to be used
       * in cases where a parser is used that is not HTML context-aware.
       */
      UNDEFINED,
      /**
       * Regular inner text HTML context.
       */
      TEXT,
      /**
       * HTML attribute context.
       */
      ATTRIBUTE,
      /**
       * At the very start of an attribute.
       */
      ATTRIBUTE_START,
    }

    private final Type type;
    private final String tag;
    private final String attribute;

    /**
     * Creates a HTML context.
     *
     * @param type the {@link Type} of this context
     */
    public HtmlContext(Type type) {
      this(type, null, null);
    }

    /**
     * Creates a HTML context.
     *
     * @param type the {@link Type} of this context
     * @param tag the HTML tag this context corresponds to, if applicable; null
     *        otherwise
     * @param attribute the HTML attribute this context corresponds to, if
     *        applicable; null otherwise
     */
    public HtmlContext(Type type, String tag, String attribute) {
      Preconditions.checkArgument((type != Type.UNDEFINED)
          || ((tag == null) && (attribute == null)),
          "tag and attribute must be null for context \"UNDEFINED\"");
      Preconditions.checkArgument((type != Type.TEXT)
          || ((tag == null) && (attribute == null)),
          "tag and attribute must be null for context \"TEXT\"");
      this.type = type;
      this.tag = tag;
      this.attribute = attribute;
    }

    /**
     * Returns the attribute of this HTML context.
     */
    public String getAttribute() {
      return attribute;
    }

    /**
     * Returns the tag of this HTML context.
     */
    public String getTag() {
      return tag;
    }

    /**
     * Returns the type of this HTML context.
     */
    public Type getType() {
      return type;
    }

    @Override
    public String toString() {
      return "(" + getType() + "," + getTag() + "," + getAttribute() + ")";
    }
  }

  /**
   * Represents a template chunk corresponding to a literal string.
   */
  static final class LiteralChunk implements TemplateChunk {
    private final StringBuilder chunk;

    /**
     * Creates a literal chunk corresponding to an empty string.
     */
    public LiteralChunk() {
      chunk = new StringBuilder();
    }

    /**
     * Creates a literal chunk corresponding to the provided string.
     */
    public LiteralChunk(String literal) {
      chunk = new StringBuilder(literal);
    }

    public Kind getKind() {
      return Kind.LITERAL;
    }

    public String getLiteral() {
      return chunk.toString();
    }

    @Override
    public String toString() {
      return String.format("L(%s)", getLiteral());
    }

    void append(String s) {
      chunk.append(s);
    }
  }

  /**
   * Represents a template chunk corresponding to a template parameter.
   */
  static final class ParameterChunk implements TemplateChunk {

    private final HtmlContext context;
    private final int parameterIndex;

    /**
     * Creates a parameter chunk.
     *
     * @param context the HTML context this parameter appears in
     * @param parameterIndex the index of the template parameter that this chunk
     *        refers to
     */
    public ParameterChunk(HtmlContext context, int parameterIndex) {
      this.context = context;
      this.parameterIndex = parameterIndex;
    }

    /**
     * Returns the HTML context this parameter appears in.
     */
    public HtmlContext getContext() {
      return context;
    }

    public Kind getKind() {
      return Kind.PARAMETER;
    }

    /**
     * Returns the index of the template parameter that this chunk refers to.
     */
    public int getParameterIndex() {
      return parameterIndex;
    }

    @Override
    public String toString() {
      return String.format("P(%s,%d)", getContext(), getParameterIndex());
    }
  }

  /**
   * Represents a parsed chunk of a template.
   * 
   * <p>There are two kinds of chunks: Those representing literal strings and
   * those representing template parameters.
   */
  interface TemplateChunk {
    /**
     * Distinguishes different kinds of {@link TemplateChunk}.
     */
    public static enum Kind {
      LITERAL, PARAMETER,
    }

    /**
     * Returns the {@link Kind} of this template chunk.
     */
    Kind getKind();
  }

  /*
   * The chunks of this parsed template.
   */
  private final LinkedList<TemplateChunk> chunks;

  /**
   * Initializes an empty parsed HTML template.
   */
  public ParsedHtmlTemplate() {
    chunks = new LinkedList<TemplateChunk>();
  }

  /**
   * Adds a literal string to the template.
   * 
   * If the currently last chunk of the parsed template is a literal chunk, the
   * provided string literal will be appended to that chunk. I.e., consecutive
   * literal chunks are automatically coalesced.

   * @param literal the string to be added as a literal chunk
   */
  public void addLiteral(String literal) {
    if (chunks.isEmpty()
        || (chunks.getLast().getKind() != TemplateChunk.Kind.LITERAL)) {
      chunks.add(new LiteralChunk(literal));
    } else {
      ((LiteralChunk) chunks.getLast()).append(literal);
    }
  }

  /**
   * Adds a parameter chunk to the template.
   * 
   * @param chunk the chunk to be added
   */
  public void addParameter(ParameterChunk chunk) {
    chunks.add(chunk);
  }

  /**
   * Returns the chunks of this parsed template.
   * 
   * <p>The returned list is unmodifiable.
   */
  public List<TemplateChunk> getChunks() {
    return Collections.unmodifiableList(chunks);
  }

  @Override
  public String toString() {
    return chunks.toString();
  }
}
