// 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.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();
    List<Object> compare = readResult(new String(readFile(new File(packagePath + "result/" + code + ".txt")), "UTF-8").replace("&lt;", "<").replace("&gt;", ">").replace("&nbsp;", " ").replace("&amp;", "&"), removeJSLineNumbering);
//        assertArrayEquals(code + "\n" + compare + "\n" + decorations, compare.toArray(), decorations.toArray()); // for debug
    assertArrayEquals(code, compare.toArray(), decorations.toArray());
  }

  @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, "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(null, "issue20", 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;
  }
}
