/*
 * 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.core.ext.linker.impl;

import com.google.gwt.util.tools.Utility;

import com.gargoylesoftware.htmlunit.AlertHandler;
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.MockWebConnection;
import com.gargoylesoftware.htmlunit.Page;
import com.gargoylesoftware.htmlunit.WebClient;

import junit.framework.TestCase;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * Tests the JavaScript code in the selection script test using HtmlUnit.
 */
public class SelectionScriptJavaScriptTest extends TestCase {
  private static String TEST_MODULE_NAME = "test.Module";

  /**
   * Return script code that includes the definition of computeScriptBase(),
   * most of the variables it needs to run, and a call to the function. It
   * assumes that the metaProps variable is already in scope.
   */
  private static String loadComputeScriptBase() throws IOException {
    StringBuilder code = new StringBuilder();
    code.append("var base = \"\", $doc=document;\n");
    code.append("__gwt_getMetaProperty = function(name) { "
                 + "var value = metaProps[name];"
                 + "return (value == null) ? null : value; }");
    code.append(Utility.getFileFromClassPath(SelectionScriptLinker.COMPUTE_SCRIPT_BASE_JS));
    code.append("computeScriptBase();\n");
    return code.toString();
  }

  /**
   * Return script code that includes the definition of processMetas(), all
   * variables it needs to run, and a call to the function.
   */
  private static String loadProcessMetas() throws IOException {
    StringBuilder code = new StringBuilder();
    code.append("var metaProps = { }, propertyErrorFunc, onLoadErrorFunc;\n");
    code.append(Utility.getFileFromClassPath(SelectionScriptLinker.PROCESS_METAS_JS));
    code.append("processMetas();\n");
    return code.toString().replaceAll("__MODULE_NAME__", TEST_MODULE_NAME);
  }

  /**
   * Test a meta tag specifying a base for this module
   */
  public void testModuleSpecificMetas1() throws IOException {
    StringBuilder metas = new StringBuilder();
    metas.append("<meta name=\"" + TEST_MODULE_NAME
        + "::gwt:property\" content=\"baseUrl=http://new/base\">\n");

    StringBuilder testCode = new StringBuilder();
    testCode.append(loadProcessMetas());
    testCode.append("alert('baseUrl='+metaProps['baseUrl']);\n");

    List<String> alerts = loadPage(makeHostPage(metas), testCode);

    assertEquals(1, alerts.size());
    assertEquals("baseUrl=http://new/base", alerts.get(0));
  }

  /**
   * Test a meta tag specifying a base for a different module.
   */
  public void testModuleSpecificMetas2() throws IOException {
    StringBuilder metas = new StringBuilder();
    metas.append("<meta name=\"some.other.module::gwt:property\" content=\"baseUrl=http://new/base\">\n");

    StringBuilder testCode = new StringBuilder();
    testCode.append(loadProcessMetas());
    testCode.append("alert('baseUrl='+metaProps['baseUrl']);\n");

    List<String> alerts = loadPage(makeHostPage(metas), testCode);

    assertEquals(1, alerts.size());
    assertEquals("baseUrl=undefined", alerts.get(0));
  }

  /**
   * Test that all the meta tags are extracted.
   */
  public void testProcessMetas() throws FailingHttpStatusCodeException,
      MalformedURLException, IOException {
    StringBuilder metas = new StringBuilder();
    metas.append("<meta name=\"gwt:property\" content=\"baseUrl=http://new/base\">\n");
    metas.append("<meta name=\"gwt:property\" content=\"novalue\">\n");
    metas.append("<meta name=\"gwt:onPropertyErrorFn\" content=\"function() { alert('custom prop error called');}\"}>\n");
    metas.append("<meta name=\"gwt:onLoadErrorFn\" content=\"function() { alert('custom onLoad error called');}\">\n");

    StringBuilder testCode = new StringBuilder();
    testCode.append(loadProcessMetas());
    testCode.append("alert('baseUrl='+metaProps['baseUrl']);\n");
    testCode.append("alert('novalue='+metaProps['novalue']);\n");
    testCode.append("alert('absent='+metaProps['absent']);\n");
    testCode.append("propertyErrorFunc();\n");
    testCode.append("onLoadErrorFunc();\n");

    List<String> alerts = loadPage(makeHostPage(metas), testCode);

    assertEquals(5, alerts.size());
    Iterator<String> alertsIter = alerts.iterator();
    assertEquals("baseUrl=http://new/base", alertsIter.next());
    assertEquals("novalue=", alertsIter.next());
    assertEquals("absent=undefined", alertsIter.next());
    assertEquals("custom prop error called", alertsIter.next());
    assertEquals("custom onLoad error called", alertsIter.next());
  }

  /**
   * Test the default href
   */
  public void testDefault() throws IOException {
    StringBuilder testCode = new StringBuilder();
    testCode.append("var metaProps = { };\n");
    testCode.append("function isBodyLoaded() { return true; }\n");
    testCode.append(loadComputeScriptBase());
    testCode.append("alert('base='+base);\n");

    List<String> alerts = loadPage(makeHostPage(""), testCode);

    assertEquals(1, alerts.size());
    assertEquals("base=http://foo.test/", alerts.get(0));
  }

  /**
   * Test the script base with no meta properties.
   */
  public void testScriptBase() throws IOException {
    StringBuilder testCode = new StringBuilder();
    testCode.append("var metaProps = { };\n");
    testCode.append("function isBodyLoaded() { return false; }\n");
    testCode.append(loadComputeScriptBase());
    testCode.append("alert('base='+base);\n");

    List<String> alerts = loadPage(makeHostPage(""), testCode);

    assertEquals(1, alerts.size());
    assertEquals("base=http://foo.test/foo/", alerts.get(0));
  }

  /**
   * Test getting the base URL from a meta property with an absolute URL
   */
  public void testScriptBaseFromMetas() throws IOException {
    StringBuilder testCode = new StringBuilder();
    testCode.append("var metaProps = { baseUrl : \"http://static.test/fromMetaTag/\" };\n");
    testCode.append(loadComputeScriptBase());
    testCode.append("alert('base='+base);\n");

    List<String> alerts = loadPage(makeHostPage(""), testCode);

    assertEquals(1, alerts.size());
    assertEquals("base=http://static.test/fromMetaTag/", alerts.get(0));
  }

  /**
   * Test getting the base URL from a meta property with a relative URL
   */
  public void testRelativeScriptBaseFromMetas() throws IOException {
    StringBuilder testCode = new StringBuilder();
    testCode.append("var metaProps = { baseUrl : \"fromMeta/tag/\" };\n");
    testCode.append(loadComputeScriptBase());
    testCode.append("alert('base='+base);\n");

    List<String> alerts = loadPage(makeHostPage(""), testCode);

    assertEquals(1, alerts.size());
    assertEquals("base=http://foo.test/fromMeta/tag/", alerts.get(0));
  }

  /**
   * Test the script base logic for an inlined selection script.
   */
  public void testScriptBaseForInlined() throws IOException {
    StringBuilder hostPage = new StringBuilder();
    hostPage.append("<html><head>\n");
    hostPage.append("<script lang=\"javascript\"><!--\n");
    hostPage.append("var metaProps = { }\n");
    hostPage.append(loadComputeScriptBase());
    hostPage.append("alert('base='+base);\n");
    hostPage.append("--></script>\n");

    List<String> alerts = loadPage(hostPage.toString(), "");

    assertEquals(1, alerts.size());
    assertEquals("base=http://foo.test/", alerts.get(0));
  }

  /**
   * Test getting a the base URL from the HTML base tag
   */
  public void testScriptBaseFromBaseTag() throws IOException {
    StringBuilder hostPage = new StringBuilder();
    hostPage.append("<html><head>\n");
    hostPage.append("<base href=\"http://static.test/fromBaseTag/\">\n");
    hostPage.append("<script lang=\"javascript\"><!--\n");
    hostPage.append("var metaProps = { }\n");
    hostPage.append(loadComputeScriptBase());
    hostPage.append("alert('base='+base);\n");
    hostPage.append("--></script>\n");

    List<String> alerts = loadPage(hostPage.toString(), "");

    assertEquals(1, alerts.size());
    assertEquals("base=http://static.test/fromBaseTag/", alerts.get(0));
  }

  /**
   * Test the script base logic for an inlined selection script.
   */
  public void testNocacheJsTag() throws IOException {
    StringBuilder hostPage = new StringBuilder();
    hostPage.append("<html><head>\n");
    hostPage.append("<script lang='javascript' type='application/javascript' ");
    hostPage.append("src='from/nocache/__MODULE_NAME__.nocache.js'></script>\n");
    hostPage.append("<script lang=\"javascript\"><!--\n");
    hostPage.append("var metaProps = { }\n");
    hostPage.append(loadComputeScriptBase());
    hostPage.append("alert('base='+base);\n");
    hostPage.append("--></script>\n");

    List<String> alerts = loadPage(hostPage.toString(), "");

    assertEquals(1, alerts.size());
    assertEquals("base=http://foo.test/from/nocache/", alerts.get(0));
  }

  /**
   * Load a page and return all alerts that it generates.
   */
  private List<String> loadPage(String hostPage, CharSequence testScript)
      throws FailingHttpStatusCodeException, MalformedURLException, IOException {
    WebClient webClient = new WebClient();

    // Make a mock web connection that can return the host page and the test
    // script
    MockWebConnection webConnection = new MockWebConnection();
    webConnection.setDefaultResponse(hostPage, "text/html");
    webConnection.setResponse(new URL(
        "http://foo.test/foo/test.Module.nocache.js"), testScript.toString(),
        "application/javascript");
    webConnection.setResponse(new URL(
            "http://foo.test/from/nocache/__MODULE_NAME__.nocache.js"),
            testScript.toString(),
            "application/javascript");
    webClient.setWebConnection(webConnection);

    final List<String> alerts = new ArrayList<String>();
    webClient.setAlertHandler(new AlertHandler() {
      @Override
      public void handleAlert(Page page, String msg) {
        alerts.add(msg);
      }
    });

    webClient.getPage("http://foo.test/");
    return alerts;
  }

  private String makeHostPage(CharSequence metas) {
    StringBuilder buf = new StringBuilder();
    buf.append("<html><head>\n");
    buf.append(metas);
    buf.append("<script src=\"/foo/test.Module.nocache.js\">\n");
    buf.append("</head></html>");
    return buf.toString();
  }
}
