/*
 * Copyright 2010 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.shared;

import com.google.gwt.core.client.GWT;
import com.google.gwt.thirdparty.guava.common.base.Preconditions;
import com.google.gwt.thirdparty.streamhtmlparser.HtmlParser;
import com.google.gwt.thirdparty.streamhtmlparser.HtmlParserFactory;
import com.google.gwt.thirdparty.streamhtmlparser.ParseException;

/**
 * SafeHtml utilities whose implementation differs between hosted and web mode.
 *
 * <p>
 * This class has a super-source peer that provides the web-mode implementation.
 */
public class SafeHtmlHostedModeUtils {

  /**
   * If true, perform checks in server-side code.
   */
  public static final String FORCE_CHECK_COMPLETE_HTML =
      "com.google.gwt.safehtml.ForceCheckCompleteHtml";

  private static boolean forceCheckCompleteHtml;

  static {
    setForceCheckCompleteHtmlFromProperty();
  }

  /**
   * Checks if the provided HTML string is complete (ends in "inner HTML"
   * context).
   *
   * <p>
   * This method parses the provided string as HTML and determines the HTML
   * context at the end of the string. If the context is not "inner HTML text",
   * an {@link IllegalArgumentException} or {@link AssertionError} is thrown.
   *
   * <p>
   * For example, this check will pass for the following strings:
   *
   * <pre>{@code
   *   &lt;foo&gt;blah
   *   baz&lt;em&gt;foo&lt;/em&gt; &lt;x a="b"&gt;hello
   * }</pre>
   *
   * <p>
   * The check will fail for the following strings:
   *
   * <pre>{@code
   *   baz&lt;em&gt;foo&lt;/em&gt; &lt;x
   *   baz&lt;em&gt;foo&lt;/em&gt; &lt;x a="b
   *   baz&lt;em&gt;foo&lt;/em&gt; &lt;x a="b"
   * }</pre>
   *
   * <p>
   * Note that the parser is lenient and this check will pass for HTML that is
   * not well-formed, or contains invalid tags, as long as the parser can
   * determine the HTML context at the end of the string.
   *
   * <p>
   * This check is intended to assert a convention-of-use constraint of {@link
   * com.google.gwt.safehtml.shared.SafeHtmlBuilder#appendHtmlConstant(String)}.
   * Since the check is somewhat expensive, it is intended to run only in the
   * context of unit-tests or test environments, and not in production
   * environments. Hence this check will only execute under the following
   * conditions, and will be short-circuited otherwise:
   *
   * <ul>
   * <li>In client-side code in hosted mode,</li>
   * <li>In server-side code if assertions are enabled,</li>
   * <li>In server-side code if the property {@code
   * com.google.gwt.safehtml.ForceCheckCompleteHtml} is set.</li>
   * <li>In server-side code if {@link #setForceCheckCompleteHtml(boolean)} has
   * been called with a {@code true} argument.</li>
   * </ul>
   *
   * @param html the HTML to check
   */
  public static void maybeCheckCompleteHtml(String html) {
    if (GWT.isClient() || forceCheckCompleteHtml) {
      Preconditions.checkArgument(isCompleteHtml(html),
          "String is not complete HTML (ends in non-inner-HTML context): %s",
          html);
    } else {
      assert isCompleteHtml(html) :
          "String is not complete HTML (ends in non-inner-HTML context): "
          + html;
    }
  }

  /**
   * Sets a global flag that controls whether or not
   * {@link #maybeCheckCompleteHtml(String)} should perform its check in a
   * server-side environment.
   *
   * @param check if true, perform server-side checks.
   */
  public static void setForceCheckCompleteHtml(boolean check) {
    forceCheckCompleteHtml = check;
  }

  /**
   * Sets a global flag that controls whether or not
   * {@link #maybeCheckCompleteHtml(String)} should perform its check in a
   * server-side environment from the value of the {@value
   * FORCE_CHECK_COMPLETE_HTML} property.
   */
  // The following annotation causes javadoc to crash on Mac OS X 10.5.8,
  // using java 1.5.0_24.
  //
  // See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6442982
  //
  // @VisibleForTesting
  public static void setForceCheckCompleteHtmlFromProperty() {
    forceCheckCompleteHtml =
        System.getProperty(FORCE_CHECK_COMPLETE_HTML) != null;
  }

  private static boolean isCompleteHtml(String html) {
    HtmlParser htmlParser = HtmlParserFactory.createParser();
    try {
      htmlParser.parse(html);
    } catch (ParseException e) {
      return false;
    }
    return htmlParser.getState() == HtmlParser.STATE_TEXT;
  }
}
