// 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 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(extension, 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, "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);

        // only source but no result is provided from JavaScript Prettify
//        test(null, "issue79", 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");
        }

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