/*******************************************************************************
 * Copyright (c) 2013, 2018 Red Hat, Inc.
 *
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     Neil Guzman - perl implementation
 *******************************************************************************/
package org.eclipse.linuxtools.internal.rpmstubby.parser;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.linuxtools.internal.rpmstubby.StubbyLog;

/**
 * Class to parse a Perl Makefile.PL to grab specfile properties
 *
 */
public class PerlMakefileParser {

    /*
     * Perl Regular Expressions
     *
     */
    private static final String WHITE_SPACE = "(?:\\s+)";
    private static final String COMMENT = "#.+";                            // # comment
    private static final String LINE_WITH_COMMENT = "(?:(.*)#.+)";          // line # comment
    private static final String VARIABLE_PARAMS = "(?:my|local|our)";

    private static final String WORD = "(\\b\\w+\\b)";                      // variable
    private static final String NON_WHITE_SPACE = "(\\S+)";
    private static final String VARIABLE = "(?:" + VARIABLE_PARAMS
            + WHITE_SPACE + ")?(?:\\$|@|%)" + WORD + WHITE_SPACE + "?";     // %variable | my $variable | our @variable
    private static final String ASSOCIATIVE_KEY = WHITE_SPACE + "?"
            + NON_WHITE_SPACE + WHITE_SPACE + "?";

    private static final String EXCLUDE_SPECIALS = "(?![=~|\\-\\*\\+\\/])";
    private static final String NON_CONDITIONAL = "(?!(?:\\s*if|elsif|unless))";
    private static final String ASSIGNMENT_OPERATOR = "=";
    private static final String ASSOCIATIVE_OPERATOR = "=>";
    private static final String SIMPLE_ASSIGNMENT = NON_CONDITIONAL
            + WHITE_SPACE + "?" + VARIABLE + "(?:" + ASSIGNMENT_OPERATOR + ")"
            + EXCLUDE_SPECIALS + "(?:(.+))";                                // %var = value || [1] = [2]
    private static final String ASSOCIATIVE_ASSIGNMENT = ASSOCIATIVE_KEY
            + ASSOCIATIVE_OPERATOR + "(?:(.+))";                            // 'key' => 'value' || [1] => [2]

    private static final String FUNCTION = "\\s*" + WORD
            + "*\\s*?\\((.*)\\)\\s*";                                       // foo(bar) | foo(foo(bar)) | foo() || [1]([2])
    private static final String BEGIN_END = "(?:[^#]*<<END)";               // [CS] test<<END | <<END
    private static final String END_END = "^END$";                          // [CS]
    private static final String BEGIN_BC = "^=(?!cut)[a-z]\\S+(\\s)?\\S+";  // [CS] =test | =test test
    private static final String END_BC = "^=cut$";                          // [CS]

    private static final String MAKEFILE_FUNCTION_NAME = "WriteMakefile";
    private static final String MAKEFILE_FUNCTION = "^.*"
            + MAKEFILE_FUNCTION_NAME + WHITE_SPACE + "?\\(.*$";

    /*
     * A few common opening characters and their closing counterparts
     *
     */
    private static final Map<Character, Character> SURROUNDING_CHARACTER;
    static {
        Map<Character, Character> aMap = new HashMap<>();
        aMap.put('[', ']');
        aMap.put('{', '}');
        aMap.put('(', ')');
        aMap.put(']', '[');
        aMap.put('}', '{');
        aMap.put(')', '(');
        SURROUNDING_CHARACTER = Collections.unmodifiableMap(aMap);
    }

    private static final char SQUARE_BRACKET = '[';
    private static final char CURLY_BRACKET = '{';
    private static final char ROUND_BRACKET = '(';

    private static final int IN_BRACKETS = 0x00000001;
    private static final int MAKE_FUNCTION = 0x00000002;

    private IFile file;
    private Map<String, String> mVariableDefinitions;
    private Map<String, String> mMakefileDefinitions;

    /**
     * Initialize.
     *
     * @param file
     *            The perl Makefile.
     * @throws CoreException
     *             Throws CoreException.
     * @throws IOException
     *             Throws IOException.
     */
    public PerlMakefileParser(IFile file) throws IOException, CoreException {
        mVariableDefinitions = new HashMap<>();
        mMakefileDefinitions = new HashMap<>();
        if (file.getContents().available() <= 0) {
            return;
        }
        this.file = file;
        parse();
    }

    /**
     * Parse the perl Makefile.
     *
     */
    public void parse() {
        String content = "";
        String line = "";
        try (Scanner variableScanner = new Scanner(file.getContents())) {
            grabSimpleDefinitions(cleanUpContent(variableScanner));
            cleanupVariables(mVariableDefinitions);
            resolveVariables(mVariableDefinitions);

            /*
             * Going through the makefile function's attributes
             */
            if (!mVariableDefinitions.containsKey(MAKEFILE_FUNCTION_NAME)) {
                return;
            }
            try (Scanner makefileScanner = new Scanner(
                    mVariableDefinitions.get(MAKEFILE_FUNCTION_NAME))) {
                makefileScanner.useDelimiter("(?<=,)");
                ArrayList<String> makefileList = new ArrayList<>();

                while (makefileScanner.hasNext()) {
                    line = makefileScanner.next();
                    if (matchesAssociativeAssignment(line)) {
                        makefileList.add(line);
                    } else if (!makefileList.isEmpty()) {
                        makefileList.set(makefileList.size() - 1, makefileList
                                .get(makefileList.size() - 1).concat(line));
                    }
                }

                for (String str : makefileList) {
                    content = content.concat(str + '\n');
                }
                grabAssociativeDefinitions(content);
                cleanupVariables(mMakefileDefinitions);
                resolveVariables(mMakefileDefinitions);

            }
            variableScanner.close();
        } catch (CoreException e) {
            StubbyLog.logError(e);
        }
    }

    /**
     * Get the value of the variable.
     *
     * @param key The variable to get the value of.
     * @return The value of the variable.
     */
    public String getValue(String key) {
        String rc = "";
        if (mMakefileDefinitions.containsKey(key)) {
            rc = mMakefileDefinitions.get(key);
        }
        return rc;
    }

    /**
     * Get the list of values from the variable.
     *
     * @param key The variable to get the value of.
     * @return The list of values from the variable.
     */
    public List<String> getValueList(String key) {
        List<String> rc = new ArrayList<>();
        String var = "";
        if (mMakefileDefinitions.containsKey(key)) {
            var = mMakefileDefinitions.get(key);
            String[] tmp = var.split(",");
            for (String str : tmp) {
                str = cleanUpString(str);
                rc.add(str);
            }
        }
        return rc;
    }

    /**
     * Grab the simple key->value pairs from some content.
     *
     * @param content
     *            The content to grab the key->value pairs from.
     */
    private void grabSimpleDefinitions(String content) {
        try (Scanner scanner = new Scanner(content)) {
            Stack<Character> brackets = new Stack<>();
            String key = "";
            String value = "";
            String tempVar = "";
            String line = "";
            String[] tmp;
            int flags = 0;

            while (scanner.hasNext()) {
                line = scanner.nextLine();
                if (matchesSimpleAssignment(line)) {
                    tmp = line.split("=");
                    key = removeVariableSigils(tmp[0]).toLowerCase()
                            .replaceAll("\\W", "");
                    value = tmp[1];
                    if (containsOpener(value)) {
                        flags |= IN_BRACKETS;
                    } else {
                        mVariableDefinitions.put(key, value);
                    }
                } else if (containsMakefileFunction(line)) {
                    flags |= MAKE_FUNCTION;
                    flags |= IN_BRACKETS;
                }
                if ((flags & IN_BRACKETS) == IN_BRACKETS) {
                    checkBrackets(brackets, line);
                    tempVar = tempVar.concat(line.trim());
                    if (brackets.isEmpty()) {
                        if ((flags & MAKE_FUNCTION) == MAKE_FUNCTION) {
                            mVariableDefinitions
                                    .putAll(extractFunction(tempVar));
                        } else {
                            tmp = tempVar.split("=[^>]");
                            key = removeVariableSigils(tmp[0]).toLowerCase()
                                    .replaceAll("\\W", "");
                            value = tmp[1];
                            mVariableDefinitions.put(key, value);
                        }
                        tempVar = "";
                        flags &= 0;
                    }
                }
            }
        }
    }

    /**
     * Grab the associative key=>value pairs from some content.
     *
     * @param content
     *            The content to grab the key=>value pairs from.
     */
    private void grabAssociativeDefinitions(String content) {
        try (Scanner scanner = new Scanner(content)) {
            Stack<Character> brackets = new Stack<>();
            String key = "";
            String value = "";
            String tempVar = "";
            String line = "";
            String[] tmp;
            int flags = 0;

            while (scanner.hasNext()) {
                line = scanner.nextLine();
                if (matchesAssociativeAssignment(line)
                        && (flags & IN_BRACKETS) != IN_BRACKETS) {
                    tmp = line.split("=>");
                    key = removeVariableSigils(tmp[0].toLowerCase().replaceAll(
                            "\\W", ""));
                    value = tmp[1];
                    if (containsOpener(value)) {
                        flags |= IN_BRACKETS;
                    } else {
                        mMakefileDefinitions.put(key, value);
                    }
                }
                if ((flags & IN_BRACKETS) == IN_BRACKETS) {
                    checkBrackets(brackets, line);
                    tempVar = tempVar.concat(line.trim());
                    if (brackets.isEmpty()) {
                        key = removeVariableSigils(tempVar
                                .substring(0, tempVar.indexOf("=>"))
                                .toLowerCase().replaceAll("\\W", ""));
                        value = tempVar.substring(tempVar.indexOf("=>") + 2);
                        mMakefileDefinitions.put(key, value);
                        tempVar = "";
                        flags &= 0;
                    }
                }
            }
        }
    }

    /**
     * Check if the line is within a set of brackets. Update the stack tracking
     * bracket completeness.
     *
     * @param brackets
     *            The stack tracking the bracket completeness.
     * @param line
     *            The line to parse for brackets.
     */
    public static void checkBrackets(Stack<Character> brackets, String line) {
        for (char c : line.toCharArray()) {
            if (c == SQUARE_BRACKET || c == CURLY_BRACKET || c == ROUND_BRACKET) {
                brackets.push(c);
            } else if (c == SURROUNDING_CHARACTER.get(SQUARE_BRACKET)
                    || c == SURROUNDING_CHARACTER.get(CURLY_BRACKET)
                    || c == SURROUNDING_CHARACTER.get(ROUND_BRACKET)) {
                if (brackets.peek() == SURROUNDING_CHARACTER.get(c)
                        && !brackets.isEmpty()) {
                    brackets.pop();
                }
            }
        }
    }

    /**
     * Go through the map of key->value pairings and check and see if a key has
     * another key as a value. If so, resolve that.
     *
     * @param variables
     *            The key->value pairings.
     */
    private void resolveVariables(Map<String, String> variables) {
        String tempVal = "";
        for (Entry<String,String> entry : variables.entrySet()) {
            tempVal = entry.getValue();
            if (mVariableDefinitions.containsKey(tempVal)) {
                variables.put(entry.getKey(), mVariableDefinitions.get(tempVal));
            }
        }
    }

    /**
     * Extract the function name and the contents of the function and return it
     * as a key->value pairing.
     *
     * @param line
     *            The line to extract the function from.
     * @return The key->value pairing of function and parameter(s).
     */
    public static Map<String, String> extractFunction(String line) {
        Map<String, String> rc = new HashMap<>();
        Pattern pattern = Pattern.compile(FUNCTION, Pattern.CASE_INSENSITIVE);
        Matcher variableMatcher = pattern.matcher(line);
        if (variableMatcher.find()) {
            rc.put(variableMatcher.group(1), variableMatcher.group(2));
        }
        return rc;
    }

    /**
     * Extract the key->value pairing from an associative assignment.
     *
     * @param line
     *            The line to extract the function from.
     * @return The key->value pairing of function and parameter(s).
     */
    public static Map<String, String> extractKeyValueAssociation(String line) {
        Map<String, String> rc = new HashMap<>();
        String key = "";
        String value = "";
        if (matchesAssociativeAssignment(line)) {
            String[] keyValue = line.split("=>");
            key = cleanUpString(keyValue[0].toLowerCase());
            value = cleanUpString(keyValue[1]);
            rc.put(key, value);
        }
        return rc;
    }

    /**
     * Utility to go through the map of variables to clean up their values.
     *
     * @param variables
     *            The map of variables to go through.
     */
    private static void cleanupVariables(Map<String, String> variables) {
        String val = "";
        for (Entry<String,String> entry : variables.entrySet()) {
            val = cleanUpString(removeVariableSigils(entry.getValue()))
                    .trim();
            if (val.startsWith("(") || val.startsWith("[")
                    || val.startsWith("{")) {
                val = val.substring(1);
            }
            if (val.endsWith(")") || val.endsWith("]") || val.endsWith("}")) {
                val = val.substring(0, val.length() - 1);
            }
            val = cleanUpString(val);
            variables.put(entry.getKey(), val);
        }
    }

    /**
     * Utility to clean up the line of some unwanted characters.
     *
     * @param line
     *            The line to clean up.
     * @return The cleaned up version of the line.
     */
    private static String cleanUpString(String line) {
        line = line.trim().replaceAll("('|\")", "");
        if (line.endsWith(";")) {
            line = line.substring(0, line.length() - 1);
        }
        if (line.endsWith(",")) {
            line = line.substring(0, line.length() - 1);
        }
        return line;
    }

    /**
     * Remove the variable sigils.
     *
     * @param variable
     *            The variable to remove sigils from.
     * @return A word only variable with no sigils.
     */
    public static String removeVariableSigils(String variable) {
        return variable
                .replaceAll(
                        "(\\bmy\\b|\\bour\\b|\\blocal\\b|(\\\\)?\\$|(\\\\)?@|(\\\\)?%)",
                        "");
    }

    /**
     * Clean up the contents of the file and remove all the comments, END
     * blocks, and block comments.
     *
     * @param scanner
     *            The scanner of the file to be read.
     * @return The cleaned up content.
     */
    private static String cleanUpContent(Scanner scanner) {
        String rc = "";
        String line = "";
        boolean flagEND = true;
        boolean flagBC = true;
        while (scanner.hasNext()) {
            line = scanner.nextLine();
            // ignore lines between ENDS
            if (containsBeginEND(line)) {
                flagEND = false;
            } else if (matchesEndEND(line)) {
                line = scanner.nextLine();
                flagEND = true; // true
            }
            // ignore lines between =someword and =cut
            if (matchesBeginBC(line)) {
                flagBC = false;
            } else if (matchesEndBC(line)) {
                line = scanner.nextLine();
                flagBC = true;
            }
            // remove the comments
            if (matchesLineWithComment(line)) {
                line = line.replaceAll(COMMENT, "");
            }
            // if not empty line or within comment/END block
            if (flagEND && flagBC && !line.trim().equals("")) {
                rc = rc.concat(line + '\n');
            }
        }
        return rc;
    }

    /**
     * Check if a line contains a function.
     *
     * @param line
     *            The line to check.
     * @return True if the line contains a function.
     */
    public static boolean containsFunction(String line) {
        boolean rc = false;
        Pattern pattern = Pattern.compile(FUNCTION, Pattern.CASE_INSENSITIVE);
        Matcher variableMatcher = pattern.matcher(line);
        if (variableMatcher.find()) {
            rc = true;
        }
        return rc;
    }

    /**
     * Check to see if the line contains the WriteMakefile function.
     *
     * @param line
     *            The line to check.
     * @return True if the line contains the WriteMakefile function.
     */
    public static boolean containsMakefileFunction(String line) {
        boolean rc = false;
        Pattern pattern = Pattern.compile(MAKEFILE_FUNCTION,
                Pattern.CASE_INSENSITIVE);
        Matcher variableMatcher = pattern.matcher(line);
        if (variableMatcher.find()) {
            rc = true;
        }
        return rc;
    }

    /**
     * Check to see if the line contains an opening bracket.
     *
     * @param line
     *            The line to check.
     * @return True if the line contains an opening bracket.
     */
    public static boolean containsOpener(String line) {
        boolean rc = false;
        Pattern pattern = Pattern.compile("(\\(|\\[|\\{)",
                Pattern.CASE_INSENSITIVE);
        Matcher variableMatcher = pattern.matcher(line);
        if (variableMatcher.find()) {
            rc = true;
        }
        return rc;
    }

    /**
     * Check if a line contains <<END. It is case-sensitive.
     *
     * @param line
     *            The line to check.
     * @return True if the line contains <<END.
     */
    public static boolean containsBeginEND(String line) {
        boolean rc = false;
        Pattern pattern = Pattern.compile(BEGIN_END);
        Matcher variableMatcher = pattern.matcher(line);
        if (variableMatcher.find()) {
            rc = true;
        }
        return rc;
    }

    /**
     * Check if a line is a simple assignment of a variable.
     *
     * @param line
     *            The line to check.
     * @return True if the line is a simple assignment of a variable.
     */
    public static boolean matchesSimpleAssignment(String line) {
        boolean rc = false;
        Pattern pattern = Pattern.compile(SIMPLE_ASSIGNMENT,
                Pattern.CASE_INSENSITIVE);
        Matcher variableMatcher = pattern.matcher(line);
        if (variableMatcher.matches()) {
            rc = true;
        }
        return rc;
    }

    /**
     * Check if a line is a simple assignment of a variable.
     *
     * @param line
     *            The line to check.
     * @return True if the line is a simple assignment of a variable.
     */
    public static boolean matchesAssociativeAssignment(String line) {
        boolean rc = false;
        Pattern pattern = Pattern.compile(ASSOCIATIVE_ASSIGNMENT,
                Pattern.CASE_INSENSITIVE);
        Matcher variableMatcher = pattern.matcher(line);
        if (variableMatcher.matches()) {
            rc = true;
        }
        return rc;
    }

    /**
     * Check if a line matches the END. It is case-sensitive.
     *
     * @param line
     *            The line to check.
     * @return True if the line matches END.
     */
    public static boolean matchesEndEND(String line) {
        boolean rc = false;
        Pattern pattern = Pattern.compile(END_END);
        Matcher variableMatcher = pattern.matcher(line);
        if (variableMatcher.matches()) {
            rc = true;
        }
        return rc;
    }

    /**
     * Check if a line matches the beginning of a block comment. It is
     * case-sensitive.
     *
     * @param line
     *            The line to check.
     * @return True if the line matches the beginning of a block comment.
     */
    public static boolean matchesBeginBC(String line) {
        boolean rc = false;
        Pattern pattern = Pattern.compile(BEGIN_BC);
        Matcher variableMatcher = pattern.matcher(line);
        if (variableMatcher.matches()) {
            rc = true;
        }
        return rc;
    }

    /**
     * Check if a line matches the end of a block comment (=cut). It is
     * case-sensitive.
     *
     * @param line
     *            The line to check.
     * @return True if the line matches =cut.
     */
    public static boolean matchesEndBC(String line) {
        boolean rc = false;
        Pattern pattern = Pattern.compile(END_BC);
        Matcher variableMatcher = pattern.matcher(line);
        if (variableMatcher.matches()) {
            rc = true;
        }
        return rc;
    }

    /**
     * Check if a line matches that of a line with a comment.
     *
     * @param line
     *            The line to check.
     * @return True if the line matches that of a line with a comment.
     */
    public static boolean matchesLineWithComment(String line) {
        boolean rc = false;
        Pattern pattern = Pattern.compile(LINE_WITH_COMMENT,
                Pattern.CASE_INSENSITIVE);
        Matcher variableMatcher = pattern.matcher(line);
        if (variableMatcher.matches()) {
            rc = true;
        }
        return rc;
    }
}
