/*
 * 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.annotations.VisibleForTesting;
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 {

  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",
   * a {@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 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.
   */
  public static void setForceCheckCompleteHtml(boolean check) {
    forceCheckCompleteHtml = check;
  }

  @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;
  }
}
