/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you 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 org.apache.hadoop.yarn.webapp.hamlet;

import com.google.common.base.Joiner;
import static com.google.common.base.Preconditions.*;
import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;

import java.io.PrintWriter;
import java.util.EnumSet;
import static java.util.EnumSet.*;
import java.util.Iterator;

import static org.apache.commons.lang.StringEscapeUtils.*;
import static org.apache.hadoop.yarn.webapp.hamlet.HamletImpl.EOpt.*;

import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.yarn.webapp.SubView;
import org.apache.hadoop.yarn.webapp.WebAppException;


/**
 * A simple unbuffered generic hamlet implementation.
 *
 * Zero copy but allocation on every element, which could be
 * optimized to use a thread-local element pool.
 *
 * Prints HTML as it builds. So the order is important.
 */
@InterfaceAudience.Private
public class HamletImpl extends HamletSpec {
  private static final String INDENT_CHARS = "  ";
  private static final Splitter SS = Splitter.on('.').
      omitEmptyStrings().trimResults();
  private static final Joiner SJ = Joiner.on(' ');
  private static final Joiner CJ = Joiner.on(", ");
  static final int S_ID = 0;
  static final int S_CLASS = 1;

  int nestLevel;
  int indents; // number of indent() called. mostly for testing.
  private final PrintWriter out;
  private final StringBuilder sb = new StringBuilder(); // not shared
  private boolean wasInline = false;

  /**
   * Element options. (whether it needs end tag, is inline etc.)
   */
  public enum EOpt {
    /** needs end(close) tag */
    ENDTAG,
    /** The content is inline */
    INLINE,
    /** The content is preformatted */
    PRE
  };

  /**
   * The base class for elements
   * @param <T> type of the parent (containing) element for the element
   */
  public class EImp<T extends _> implements _Child {
    private final String name;
    private final T parent; // short cut for parent element
    private final EnumSet<EOpt> opts; // element options

    private boolean started = false;
    private boolean attrsClosed = false;

    EImp(String name, T parent, EnumSet<EOpt> opts) {
      this.name = name;
      this.parent = parent;
      this.opts = opts;
    }

    @Override
    public T _() {
      closeAttrs();
      --nestLevel;  
      printEndTag(name, opts);
      return parent;
    }

    protected void _p(boolean quote, Object... args) {
      closeAttrs();
      for (Object s : args) {
        if (!opts.contains(PRE)) {
          indent(opts);
        }
        out.print(quote ? escapeHtml(String.valueOf(s))
                        : String.valueOf(s));
        if (!opts.contains(INLINE) && !opts.contains(PRE)) {
          out.println();
        }
      }
    }

    protected void _v(Class<? extends SubView> cls) {
      closeAttrs();
      subView(cls);
    }

    protected void closeAttrs() {
      if (!attrsClosed) {
        startIfNeeded();
        ++nestLevel;
        out.print('>');
        if (!opts.contains(INLINE) && !opts.contains(PRE)) {
          out.println();
        }
        attrsClosed = true;
      }
    }

    protected void addAttr(String name, String value) {
      checkState(!attrsClosed, "attribute added after content");
      startIfNeeded();
      printAttr(name, value);
    }

    protected void addAttr(String name, Object value) {
      addAttr(name, String.valueOf(value));
    }

    protected void addMediaAttr(String name, EnumSet<Media> media) {
      // 6.13 comma-separated list
      addAttr(name, CJ.join(media));
    }

    protected void addRelAttr(String name, EnumSet<LinkType> types) {
      // 6.12 space-separated list
      addAttr(name, SJ.join(types));
    }

    private void startIfNeeded() {
      if (!started) {
        printStartTag(name, opts);
        started = true;
      }
    }

    protected void _inline(boolean choice) {
      if (choice) {
        opts.add(INLINE);
      } else {
        opts.remove(INLINE);
      }
    }

    protected void _endTag(boolean choice) {
      if (choice) {
        opts.add(ENDTAG);
      } else {
        opts.remove(ENDTAG);
      }
    }

    protected void _pre(boolean choice) {
      if (choice) {
        opts.add(PRE);
      } else {
        opts.remove(PRE);
      }
    }
  }

  public class Generic<T extends _> extends EImp<T> implements PCData {
    Generic(String name, T parent, EnumSet<EOpt> opts) {
      super(name, parent, opts);
    }

    public Generic<T> _inline() {
      super._inline(true);
      return this;
    }

    public Generic<T> _noEndTag() {
      super._endTag(false);
      return this;
    }

    public Generic<T> _pre() {
      super._pre(true);
      return this;
    }

    public Generic<T> _attr(String name, String value) {
      addAttr(name, value);
      return this;
    }

    public Generic<Generic<T>> _elem(String name, EnumSet<EOpt> opts) {
      closeAttrs();
      return new Generic<Generic<T>>(name, this, opts);
    }

    public Generic<Generic<T>> elem(String name) {
      return _elem(name, of(ENDTAG));
    }

    @Override
    public Generic<T> _(Object... lines) {
      _p(true, lines);
      return this;
    }

    @Override
    public Generic<T> _r(Object... lines) {
      _p(false, lines);
      return this;
    }
  }

  public HamletImpl(PrintWriter out, int nestLevel, boolean wasInline) {
    this.out = out;
    this.nestLevel = nestLevel;
    this.wasInline = wasInline;
  }

  public int nestLevel() {
    return nestLevel;
  }

  public boolean wasInline() {
    return wasInline;
  }

  public void setWasInline(boolean state) {
    wasInline = state;
  }

  public PrintWriter getWriter() {
    return out;
  }

  /**
   * Create a root-level generic element.
   * Mostly for testing purpose.
   * @param <T> type of the parent element
   * @param name of the element
   * @param opts {@link EOpt element options}
   * @return the element
   */
  public <T extends _>
  Generic<T> root(String name, EnumSet<EOpt> opts) {
    return new Generic<T>(name, null, opts);
  }

  public <T extends _> Generic<T> root(String name) {
    return root(name, of(ENDTAG));
  }

  protected void printStartTag(String name, EnumSet<EOpt> opts) {
    indent(opts);
    sb.setLength(0);
    out.print(sb.append('<').append(name).toString()); // for easier mock test
  }

  protected void indent(EnumSet<EOpt> opts) {
    if (opts.contains(INLINE) && wasInline) {
      return;
    }
    if (wasInline) {
      out.println();
    }
    wasInline = opts.contains(INLINE) || opts.contains(PRE);
    for (int i = 0; i < nestLevel; ++i) {
      out.print(INDENT_CHARS);
    }
    ++indents;
  }

  protected void printEndTag(String name, EnumSet<EOpt> opts) {
    if (!opts.contains(ENDTAG)) {
      return;
    }
    if (!opts.contains(PRE)) {
      indent(opts);
    } else {
      wasInline = opts.contains(INLINE);
    }
    sb.setLength(0);
    out.print(sb.append("</").append(name).append('>').toString()); // ditto
    if (!opts.contains(INLINE)) {
      out.println();
    }
  }

  protected void printAttr(String name, String value) {
    sb.setLength(0);
    sb.append(' ').append(name);
    if (value != null) {
      sb.append("=\"").append(value).append("\"");
    }
    out.print(sb.toString());
  }

  /**
   * Sub-classes should override this to do something interesting.
   * @param cls the sub-view class
   */
  protected void subView(Class<? extends SubView> cls) {
    indent(of(ENDTAG)); // not an inline view
    sb.setLength(0);
    out.print(sb.append('[').append(cls.getName()).append(']').toString());
    out.println();
  }

  /**
   * Parse selector into id and classes
   * @param selector in the form of (#id)?(.class)*
   * @return an two element array [id, "space-separated classes"].
   *         Either element could be null.
   * @throws WebAppException when both are null or syntax error.
   */
  public static String[] parseSelector(String selector) {
    String[] result = new String[]{null, null};
    Iterable<String> rs = SS.split(selector);
    Iterator<String> it = rs.iterator();
    if (it.hasNext()) {
      String maybeId = it.next();
      if (maybeId.charAt(0) == '#') {
        result[S_ID] = maybeId.substring(1);
        if (it.hasNext()) {
          result[S_CLASS] = SJ.join(Iterables.skip(rs, 1));
        }
      } else {
        result[S_CLASS] = SJ.join(rs);
      }
      return result;
    }
    throw new WebAppException("Error parsing selector: "+ selector);
  }

  /**
   * Set id and/or class attributes for an element.
   * @param <E> type of the element
   * @param e the element
   * @param selector Haml form of "(#id)?(.class)*"
   * @return the element
   */
  public static <E extends CoreAttrs> E setSelector(E e, String selector) {
    String[] res = parseSelector(selector);
    if (res[S_ID] != null) {
      e.$id(res[S_ID]);
    }
    if (res[S_CLASS] != null) {
      e.$class(res[S_CLASS]);
    }
    return e;
  }

  public static <E extends LINK> E setLinkHref(E e, String href) {
    if (href.endsWith(".css")) {
      e.$rel("stylesheet"); // required in html5
    }
    e.$href(href);
    return e;
  }

  public static <E extends SCRIPT> E setScriptSrc(E e, String src) {
    if (src.endsWith(".js")) {
      e.$type("text/javascript"); // required in html4
    }
    e.$src(src);
    return e;
  }
}
