/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.apache.vxquery.xtest;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.tuple.Pair;
import org.apache.vxquery.exceptions.SystemException;

public class TestCaseResult {
    private static final int DISPLAY_LEN = 1000;
    private static final Pattern XML_RES_PREFIX = Pattern.compile("<\\?[xX][mM][lL][^\\?]*\\?>");

    private static final String RED = "#FF9900";
    private static final String ORANGE = "#FFCC00";
    private static final String GREEN = "#99CC00";

    TestCase testCase;

    Throwable error;

    String result;

    long time;

    String report;

    State state;

    public TestCaseResult(TestCase testCase) {
        this.testCase = testCase;
    }

    public boolean error() {
        return error != null;
    }

    public boolean userError() {
        return error instanceof SystemException;
    }

    public void compare() {
        String eErr = testCase.getExpectedError();
        report = "No result file found";
        state = State.NO_RESULT_FILE;
        if (eErr != null) {
            if (userError()) {
                String aErr = String.valueOf(((SystemException) error).getCode());
                if (eErr.equals(aErr)) {
                    report = "Result matches expected error: " + eErr;
                    state = State.EXPECTED_ERROR_GOT_SAME_ERROR;
                } else {
                    report = "Expected error: " + eErr + ", got error: " + aErr;
                    state = State.EXPECTED_ERROR_GOT_DIFFERENT_ERROR;
                }
            } else if (error()) {
                report = "Expected error: " + eErr + ", got failure: " + error;
                state = State.EXPECTED_ERROR_GOT_FAILURE;
            } else {
                report = "Expected error: " + eErr + ", got result";
                state = State.EXPECTED_ERROR_GOT_RESULT;
            }
        } else {
            if (userError()) {
                String aErr = ((SystemException) error).getCode().toString();
                report = "Expected result, Got error: " + aErr;
                state = State.EXPECTED_RESULT_GOT_ERROR;
            } else if (error()) {
                report = "Expected result, Got failure: " + error;
                state = State.EXPECTED_RESULT_GOT_FAILURE;
            } else {
                File[] resFiles = testCase.getExpectedResultFiles();
                for (int i = 0; i < resFiles.length; ++i) {
                    File resFile = resFiles[i];
                    String expResult = slurpFile(resFile);
                    if (expResult == null) {
                        report = "No result file found";
                        state = State.NO_RESULT_FILE;
                    } else {
                        expResult = expResult.trim();
                        if (result != null) {
                            Matcher m = XML_RES_PREFIX.matcher(result);
                            if (m.find() && m.start() == 0) {
                                result = result.substring(m.end());
                            }
                            result = result.trim();
                            Pair<Boolean, String> cmp = textCompare(expResult, result);
                            report = cmp.getRight();
                            state = cmp.getLeft() ? State.EXPECTED_RESULT_GOT_SAME_RESULT
                                    : State.EXPECTED_RESULT_GOT_DIFFERENT_RESULT;
                            if (cmp.getLeft()) {
                                break;
                            }
                        }
                    }
                }
            }
        }
    }

    private Pair<Boolean, String> textCompare(String expRes, String actRes) {
        boolean cmp = expRes.equals(actRes);
        if (testCase.getConfig().options.verbose) {
            System.err.println("Comparing:");
            System.err.println("Expected: ---" + expRes + "---");
            System.err.println("Actual  : ---" + actRes + "---");
            System.err.println("Result  : " + cmp);
        }
        if (cmp) {
            return Pair.<Boolean, String> of(Boolean.TRUE, "Got expected result");
        } else {
            return Pair.<Boolean, String> of(Boolean.FALSE,
                    "Expected: " + truncate(expRes) + " Got: " + truncate(actRes));
        }
    }

    private String truncate(String strArg) {
        String str = strArg;
        if (str == null) {
            return "&lt;NULL&gt;";
        }
        if (str.length() > DISPLAY_LEN) {
            str = str.substring(0, DISPLAY_LEN);
            str += "...";
        }
        return xmlEncode(str);
    }

    private String xmlEncode(String str) {
        StringBuilder buffer = new StringBuilder();
        int len = str.length();
        for (int i = 0; i < len; ++i) {
            char ch = str.charAt(i);
            switch (ch) {
                case '<':
                    buffer.append("&lt;");
                    break;

                case '>':
                    buffer.append("&gt;");
                    break;

                case '"':
                    buffer.append("&quot;");
                    break;

                case '\'':
                    buffer.append("&apos;");
                    break;

                case '&':
                    buffer.append("&amp;");
                    break;

                default:
                    buffer.append(ch);
            }
        }
        return buffer.toString();
    }

    private String slurpFile(File f) {
        StringBuilder content = new StringBuilder();
        try {
            FileReader in = new FileReader(f);
            try {
                char[] buffer = new char[8192];
                int c;
                while ((c = in.read(buffer)) >= 0) {
                    content.append(buffer, 0, c);
                }
            } finally {
                in.close();
            }
        } catch (IOException e) {
            return null;
        }
        return content.toString();
    }

    public enum State {
        EXPECTED_RESULT_GOT_SAME_RESULT(GREEN),
        EXPECTED_ERROR_GOT_SAME_ERROR(GREEN),
        EXPECTED_RESULT_GOT_DIFFERENT_RESULT(ORANGE),
        EXPECTED_RESULT_GOT_ERROR(ORANGE),
        EXPECTED_ERROR_GOT_DIFFERENT_ERROR(ORANGE),
        EXPECTED_ERROR_GOT_RESULT(ORANGE),
        EXPECTED_RESULT_GOT_FAILURE(RED),
        EXPECTED_ERROR_GOT_FAILURE(RED),
        NO_RESULT_FILE(RED);

        private String color;

        private State(String color) {
            this.color = color;
        }

        public String getColor() {
            return color;
        }
    }

}
