/*
 * 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 Development and
 * Production Mode.
 *
 * <p>
 * This class has a super-source peer that provides the Production 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
   *   <foo>blah
   *   baz<em>foo</em> <x a="b">hello
   * }</pre>
   *
   * <p>
   * The check will fail for the following strings:
   *
   * <pre>{@code
   *   baz<em>foo</em> <x
   *   baz<em>foo</em> <x a="b
   *   baz<em>foo</em> <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 Development 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;
  }
}
