// 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 = unescapeHtmlSpecialChars(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"));
    final StringBuilder plainResult = new StringBuilder();
    List<Object> compare = readResult(unescapeHtmlSpecialChars(new String(bytes, "UTF-8")), removeJSLineNumbering, plainResult);

    if (!removeJSLineNumbering) {
      assertEquals(source, plainResult.toString());
    }

    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("dart", "dart_lang", 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);
    test("tcl", "tcl_lang", false);
    test("r", "r_lang", false);
    test("erlang", "erlang", false);
    test("mumps", "mumps", false);
    test("llvm", "llvm", false);
    test("pascal", "pascal_lang", false);
    test("basic", "basic_lang", false);
    test("js", "issue217", false);
    test("matlab", "matlab", 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}
   */
  private static List<Object> readResult(String resultText, boolean removeJSLineNumbering, StringBuilder plainResult) {
    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]", "");

      // combine 'adjacent with identical decoration keyword' segments
      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();
    }

    // digest result(string) into segments by identifing standard 'decoration keyword' start & end
    int count = 0;
    Pattern decorationPattern = Pattern.compile("`([A-Z]{3})(.+?)`END|<span class=\"([a-z]+)\">(.+?)`END", Pattern.MULTILINE | Pattern.DOTALL);
    Matcher matcher = decorationPattern.matcher(_resultText);
    while (matcher.find()) {
      returnList.add(count);

      String decorationKeyword = null;
      String decoratedContent = null;

      if (matcher.group(1) != null) {
        decorationKeyword = matcher.group(1);
        decoratedContent = matcher.group(2);
      } else {
        decorationKeyword = matcher.group(3);
        decoratedContent = matcher.group(4);
      }

      returnList.add(decorationKeyword.toLowerCase());
      count += decoratedContent.length();
      plainResult.append(decoratedContent);
    }

    returnList = Util.removeDuplicates(returnList, _resultText);

    // for debug
//        StringBuffer sb = new StringBuffer();
//        matcher = decorationPattern.matcher(resultText);
//        while (matcher.find()) {
//            if (matcher.group(1) != null) {
//                matcher.appendReplacement(sb, "");
//                sb.append(matcher.group(2));
//            } else {
//                matcher.appendReplacement(sb, "");
//                sb.append(matcher.group(4));
//            }
//        }
//        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;
  }

  protected static String unescapeHtmlSpecialChars(String inputString) {
      return inputString.replace("&lt;", "<").replace("&gt;", ">").replace("&nbsp;", " ").replace("&amp;", "&");
  }

	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());
            if (end > source.length()) {
                result.append("...");
                break;
            }

			result.append(source.substring(start, end));
			result.append("`");
			result.append("END");
		}

		return result.toString();
	}
}
