// Copyright (C) 2006 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 prettify;

import prettify.parser.Util;
import prettify.parser.Job;
import prettify.parser.Prettify;

import java.util.Arrays;
import java.util.ListIterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.ArrayList;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;

/**
 * Tests are adapted from JavaScript Prettify.
 * @author Chan Wai Shing <cws1989@gmail.com>
 */
public class PrettifyTest {

  static {
    // set debug mode
    System.setProperty("PrettifyDebugMode", "true");
  }
  protected final String packagePath = "test/" + this.getClass().getCanonicalName().replace('.', '/') + "/";
  protected Prettify prettify;

  public PrettifyTest() {
  }

  protected static String getClassName() {
    return new Object() {
    }.getClass().getEnclosingClass().getName();
  }

  @BeforeClass
  public static void setUpClass() throws Exception {
    System.out.println("***** " + getClassName() + " *****");
  }

  @AfterClass
  public static void tearDownClass() throws Exception {
    System.out.println("******************************\r\n");
  }

  @Before
  public void setUp() {
    prettify = new Prettify();
  }

  @After
  public void tearDown() {
  }

  /**
   * Do test. The Java Prettify line numbering is different from JavaScript 
   * Prettify. If the result is adapted from JavaScript Prettify tests and 
   * that {@code resultText} have line numbering, set {@code removeNewLines} 
   * to true.
   * 
   * @param extension the file name of the source file
   * @param code the source code
   * @param removeJSLineNumbering true to remove new line and combine 
   * identical adjacent tag
   * 
   * @throws IOException error occurred when reading source or result file
   */
  public void test(String extension, String code, boolean removeJSLineNumbering) throws IOException {
    String source = new String(readFile(new File(packagePath + "source/" + code + ".txt")), "UTF-8");
    Job job = new Job(0, source);
    prettify.langHandlerForExtension(extension, source).decorate(job);
    List<Object> decorations = removeJSLineNumbering ? removeNewLines(job.getDecorations(), source) : job.getDecorations();
    final byte[] bytes = readFile(new File(packagePath + "result/" + code + ".txt"));
    List<Object> compare = readResult(new String(bytes, "UTF-8").replace("&lt;", "<").replace("&gt;", ">").replace("&nbsp;", " ").replace("&amp;", "&"), removeJSLineNumbering);

    if (Arrays.equals(compare.toArray(), decorations.toArray())) {
      return;
    }

    final StringBuilder errorMessage = new StringBuilder();
    errorMessage.append("Prettify failed. Expected:\n");
    errorMessage.append(prettify(source, compare));
    errorMessage.append("\n\nBut was:\n");
    errorMessage.append(prettify(source, decorations));
    fail(errorMessage.toString());
  }

  @Test
  public void testBatch() throws IOException {
    System.out.println("+++++ testBatch +++++");

    test(null, "bash", false);
    test("sh", "bash_lang", true);
    test(null, "java", false);
    test("java", "java_lang", true);
    test(null, "C", false);
    test("c", "C_lang", false);
    test(null, "Cpp", false);
    test("cpp", "Cpp_lang", false);
    test(null, "dart", false);
    test(null, "javascript", false);
    test(null, "perl", false);
    test(null, "python", false);
    test("py", "python_lang", false);
    test(null, "PHP", false);
    test("coffee", "coffee", false);
    test("css", "css", false);
    test("go", "go", false);
    test(null, "html", false);
    test(null, "htmlXmp", false);
    test("html", "html_lang", false);
    test(null, "issue12", false);
    test("js", "issue12_lang", false);
    test(null, "issue14a", false);
    test(null, "issue14b", false);
    test("sh", "issue165", false);
    test(null, "issue20", false);
    test("c", "issue201", false);
    test(null, "issue21", false);
    test("lua", "issue24", false);
    test("vb", "issue27", false);
    test("hs", "issue30", false);
    test("ml", "issue33", false);
    test(null, "issue4", false);
    test("el", "issue42", false);
    test(null, "issue45", false);
    test(null, "issue79", false);
    test(null, "issue8", false);
    test("java", "issue84", false);
    test(null, "issue92", false);
    test("cs", "issue93", false);
    test(null, "misc1", false);
    test("proto", "proto", false);
    test("scala", "scala", false);
    test("vhdl", "vhdl", false);
    test("wiki", "wiki", false);
    test(null, "xhtml", false);
    test(null, "xml", false);
    test(null, "xsl", false);
    test("yaml", "yaml1", false);
    test("yaml", "yaml2", false);
  }

  /**
   * Read the whole file and return the content in byte array.
   * @param file the file to read
   * @return the content of the file in byte array
   * @throws IOException error occurred when reading the content from the 
   * file
   */
  public static byte[] readFile(File file) throws IOException {
    if (file == null) {
      throw new NullPointerException("argument 'file' cannot be null");
    }

    long fileLength = file.length();
    byte[] content = new byte[(int) fileLength];

    FileInputStream fin = null;
    try {
      fin = new FileInputStream(file);

      int byteRead = 0, cumulateByteRead = 0;
      while ((byteRead = fin.read(content, cumulateByteRead, content.length - cumulateByteRead)) != -1) {
        cumulateByteRead += byteRead;
        if (cumulateByteRead >= fileLength) {
          break;
        }
      }

      if (cumulateByteRead != fileLength) {
        throw new IOException("The total number of bytes read does not match the file size. Actual file size: " + fileLength + ", bytes read: " + cumulateByteRead + ", path: " + file.getAbsolutePath());
      }
    } finally {
      if (fin != null) {
        try {
          fin.close();
        } catch (IOException ex) {
        }
      }
    }

    return content;
  }

  /**
   * Determine the positions of new line characters in {@code source} and 
   * adjust the position value in {@code decorations}. Finally, it will 
   * combine adjacent identical tags.
   * 
   * @param decorations see {@link prettify.Job#decorations}
   * @param source the source code in string
   * 
   * @return the adjusted list of {@code decorations}
   */
  public static List<Object> removeNewLines(List<Object> decorations, String source) {
    if (decorations == null) {
      throw new NullPointerException("argument 'decorations' cannot be null");
    }
    if (source == null) {
      throw new NullPointerException("argument 'source' cannot be null");
    }

    List<Object> _decorations = new ArrayList<Object>(decorations);

    StringBuffer sb = new StringBuffer();
    Pattern pattern = Pattern.compile("[\r\n]");
    Matcher matcher = pattern.matcher(source);
    while (matcher.find()) {
      matcher.appendReplacement(sb, "");

      int posStart = sb.length();
      ListIterator<Object> iterator = _decorations.listIterator();
      while (iterator.hasNext()) {
        Integer pos = (Integer) iterator.next();
        if (pos > posStart) {
          iterator.set(pos - 1);
        }
        iterator.next();
      }
    }
//        matcher.appendTail(sb);

    return Util.removeDuplicates(_decorations, source);
  }

  /**
   * Parse the {@code resultText}. The Java Prettify line numbering is 
   * different from JavaScript Prettify. If the result is adapted from 
   * JavaScript Prettify tests and that {@code resultText} have line 
   * numbering, set {@code removeNewLines} to true. Also, the 
   * {@code resultText} should not escape html special characters
   * 
   * @param resultText the result in string
   * @param removeJSLineNumbering true to remove new line and combine identical 
   * adjacent tag
   * 
   * @return the parsed result with format similar to 
   * {@link prettify.Job#decorations}
   */
  public static List<Object> readResult(String resultText, boolean removeJSLineNumbering) {
    if (resultText == null) {
      throw new NullPointerException("argument 'resultText' cannot be null");
    }
    String _resultText = resultText;

    List<Object> returnList = new ArrayList<Object>();

    if (removeJSLineNumbering) {
      _resultText = _resultText.replaceAll("[\r\n]", "");

      StringBuffer sb = new StringBuffer();
      Pattern pattern = Pattern.compile("(`[A-Z]{3})([^`]+?)`END\\1([^`]+?)`END", Pattern.MULTILINE | Pattern.DOTALL);
      Matcher matcher = pattern.matcher(_resultText);
      while (matcher.find()) {
        matcher.appendReplacement(sb, "");
        sb.append(matcher.group(1)).append(matcher.group(2)).append(matcher.group(3)).append("`END");
      }
      matcher.appendTail(sb);

      _resultText = sb.toString();
    }

    int count = 0;
    Pattern pattern = Pattern.compile("`([A-Z]{3})(.+?)`END", Pattern.MULTILINE | Pattern.DOTALL);
    Matcher matcher = pattern.matcher(_resultText);
    while (matcher.find()) {
      returnList.add(count);
      returnList.add(matcher.group(1).toLowerCase());
      count += matcher.group(2).length();
    }

    returnList = Util.removeDuplicates(returnList, _resultText);

    // for debug
//        StringBuffer sb = new StringBuffer();
//        matcher = pattern.matcher(resultText);
//        while (matcher.find()) {
//            matcher.appendReplacement(sb, "");
//            sb.append(matcher.group(2));
//        }
//        matcher.appendTail(sb);
//        String plainCode = sb.toString();
//
//        System.out.println(plainCode);
//
//        for (int i = 0, iEnd = returnList.size(); i < iEnd; i += 2) {
//            int end = i + 2 < iEnd ? (Integer) returnList.get(i + 2) : plainCode.length();
//            System.out.println(returnList.get(i) + ": " + returnList.get(i + 1) + ": " + plainCode.substring((Integer) returnList.get(i), end));
//        }

    return returnList;
  }

	private static String prettify(String source, List<Object> decorations) {
		if (decorations.size() % 2 != 0) {
			throw new IllegalArgumentException();
		}

		final StringBuilder result = new StringBuilder();
		for (int index = 0; index < decorations.size(); index+=2) {
			final int start = ((Integer)decorations.get(index)).intValue();
			final int end = index < decorations.size() - 2 ? ((Integer)decorations.get(index + 2)).intValue() : source.length();
			final String type = (String)decorations.get(index + 1);
			result.append("`");
			result.append(type.toUpperCase());
			result.append(source.substring(start, end));
			result.append("`");
			result.append("END");
		}

		return result.toString();
	}
}
