/*
 *  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.
 */
import java.io.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/* dkulp - Stupid little program I use to help merge changes from 
   trunk to the fixes branches.   It requires the command line version of 
   svn to be available on the path.   If using a git checkout, it also requires
   the command line version of git on the path.

   Basically, git does all the work, but this little wrapper 
   thing will display the commit logs, prompt if you want to merge/block/ignore
   each commit, prompt for commit (so you can resolve any conflicts first), 
   etc....

   Yes - doing this in python itself (or perl or even bash itself or ruby or ...) 
   would probably be better.  However, I'd then need to spend time 
   learning python/ruby/etc... that I just don't have time to do right now.
   What is more productive: Taking 30 minutes to bang this out in Java or
   spending a couple days learning another language that would allow me to
   bang it out in 15 minutes?

   Explanation of commands: 

   [B]lock will permanently block the particular commit from being merged.  
   It won't ask again on subsequent runs of DoMerge.

   [I]gnore ignores the commit for the current DoMerges run, but will ask 
   again the next time you DoMerges.  If you're not certain for a particular
   commit use this option for someone else to determine on a later run.

   [R]ecord formally records that a merge occurred, but it does *not* 
   actually merge the commit.  This is useful if you another tool to do
   the merging but still wish to record a merge did occur.

   [F]lush will permanently save all the [B]'s and [R]'s you've earlier made, 
   useful when you need to stop DoMerges (due to a missed commit or other 
   problem) before it's complete.  That way subsequent runs of DoMerges 
   won't go through the blocked/recorded items again.  (Flushes occur
   automatically when DoMerges is finished running.)

   [C]hanges will display the changes in the commit to help you decide the 
   appropriate action to take.

*/

public class DoMerges {
    public static final String MERGEINFOFILE = ".gitmergeinfo";
    
    public static boolean auto = false;
    public static Pattern jiraPattern = Pattern.compile("([A-Z]{2,10}+-\\d+)");
    public static String username;
    public static String fromBranch;
    
    public static Set<String> records = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
    public static Set<String> patchIds = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
    
    static class ToFrom {
        final String from;
        final String to;
        
        public ToFrom(String t, String f) {
            to = t;
            from = f;
        }
    }
    public static List<ToFrom> pathMaps = new LinkedList<ToFrom>();

    static int waitFor(Process p) throws Exception  {
        return waitFor(p, true);
    }
    static int waitFor(Process p, boolean exit) throws Exception  {
        int i = p.waitFor();
        if (i != 0) {
            System.out.println("ERROR!");
            BufferedReader reader = new BufferedReader(new InputStreamReader(p.getErrorStream()));
            String line = reader.readLine();
            while (line != null) {
                System.out.println(line);
                line = reader.readLine();
            }
            if (exit) {
                System.exit(1);
            }
        }
        return i;
    }
    static int runProcess(Process p) throws Exception {
        return runProcess(p, true);
    }
    static int runProcess(Process p, boolean exit) throws Exception {
        BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
        String line = reader.readLine();
        while (line != null) {
            System.out.println(line);
            line = reader.readLine();
        }
        return waitFor(p, exit);
    }
    

    static boolean doCommit() throws Exception {
        while (System.in.available() > 0) {
            System.in.read();
        }
        char c = auto ? 'Y' : 0;
        while (c != 'Y'
               && c != 'N') {
            System.out.print("Commit:  [Y]es, or [N]o? ");
            int i = System.in.read();
            c = Character.toUpperCase((char)i);
        }
        if (c == 'N') {
            Process p = Runtime.getRuntime().exec(new String[] {"git", "reset", "--hard"});
            runProcess(p);
            return false;
        }
        
        Process p = Runtime.getRuntime().exec(new String[] {"git", "commit", "--no-edit", "-a"});
        runProcess(p);
        return true;
    }   

    public static void changes(String ver) throws Exception {
        Process p = Runtime.getRuntime().exec(getCommandLine(new String[] {"git", "show", ver}));
        runProcess(p);
    }
    
    public static void flush() throws Exception {
        BufferedWriter writer = new BufferedWriter(new FileWriter(MERGEINFOFILE));
        writer.write(fromBranch);
        writer.newLine();
        for (ToFrom ent : pathMaps) {
            writer.write("A ");
            writer.write(ent.from);
            writer.write(" ");
            writer.write(ent.to);
            writer.newLine();
        }
        for (String s : records) {
            writer.write(s);
            writer.newLine();
        }
        writer.flush();
        writer.close();
        
        Process p = Runtime.getRuntime().exec(getCommandLine(new String[] {"git", "commit", "-m",
                                                                           "Recording .gitmergeinfo Changes",
                                                                           MERGEINFOFILE}));
        runProcess(p);
    }
    public static void doUpdate() throws Exception {
        Process p = Runtime.getRuntime().exec(new String[] {"git", "pull", "--rebase"});
        runProcess(p);
        
        File file = new File(MERGEINFOFILE);
        records.clear();
        if (file.exists()) {
            BufferedReader reader = new BufferedReader(new FileReader(MERGEINFOFILE));
            String line = reader.readLine();
            fromBranch = line;
            line = reader.readLine();
            while (line != null) {
                if (line.startsWith("A ")) {
                    line = line.substring(2).trim();
                    String from = line.substring(0, line.indexOf(' '));
                    String to = line.substring(line.indexOf(' ') + 1);
                    pathMaps.add(new ToFrom(to, from));
                } else {
                    records.add(line.trim());
                }
                line = reader.readLine();
            }
            reader.close();
        }
        file = new File("patch-info");
        if (file.exists()) {
            BufferedReader reader = new BufferedReader(new FileReader("patch-info"));
            String line = reader.readLine();
            while (line != null) {
                patchIds.add(line.trim());
                line = reader.readLine();
            }
            reader.close();
        }
    }

    public static List<String> getAvailableUpdates() throws Exception {
        List<String> verList = new LinkedList<String>();
        Process p;
        BufferedReader reader;
        String line;
        
        p = Runtime.getRuntime().exec(getCommandLine(new String[] {"git", "cherry",
                                                                   "HEAD", fromBranch})); 
            
        reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
        line = reader.readLine();
        while (line != null) {
            if (line.charAt(0) == '+') {
                String ver = line.substring(2).trim(); 
                if (!records.contains("B " + ver) && !records.contains("M " + ver)) {
                    verList.add(ver);
                }
            }
            line = reader.readLine();
        }
        p.waitFor();
        return verList;
    }

    public static List<String[]> getGitLogs() throws Exception {
        BufferedReader reader;
        String line;
        Process p = Runtime.getRuntime().exec(new String[] {"git", "log", fromBranch + "..HEAD"});
        reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
        line = reader.readLine();

        List<String[]> map = new LinkedList<String[]>();
        List<String> list = new ArrayList<String>(10);
        while (line != null) {
            if (line.length() > 0 && line.startsWith("commit ")) {
                if (!list.isEmpty()) {
                    map.add(list.toArray(new String[list.size()]));
                    list.clear();
                }
                while (line != null && line.length() > 0 && line.charAt(0) != ' ') {
                    list.add(line);
                    line = reader.readLine();
                }
            }
            list.add(line);
            line = reader.readLine();
        }
        if (!list.isEmpty()) {
            map.add(list.toArray(new String[list.size()]));
            list.clear();
        }
        return map;
    }
        
    public static String[] getLog(String ver, Set<String> jiras) throws Exception {
        Process p;
        BufferedReader reader;
        String line;
        p = Runtime.getRuntime().exec(new String[] {"git", "log", "--pretty=medium", "-n", "1" , ver});

        reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
        line = reader.readLine();
        List<String> lines = new ArrayList<String>(10);
        while (line != null) {
            if (!line.startsWith("commit ")) {
                lines.add(line);
                Matcher m = jiraPattern.matcher(line);
                while (m.find()) {
                    jiras.add(m.group());
                }
            }
            line = reader.readLine();
        }
        p.waitFor();
        return lines.toArray(new String[lines.size()]);
    }
        
    private static void doMerge(String ver) throws Exception {
        Process p = Runtime.getRuntime().exec(getCommandLine(new String[] {"git", "cherry-pick", ver}));
        if (runProcess(p, false) != 0) {
            p = Runtime.getRuntime().exec(getCommandLine(new String[] {"git", "status"}));
            runProcess(p);
                
            if (doCommit()) {
                records.add("M " + ver);
            }
        } else {
            String oldPatchId = getPatchId(ver);
            String newPatchId = getPatchId("HEAD");
            if (!oldPatchId.equals(newPatchId)) {
                records.add("M " + ver);
            }
        }
    }
    private static void doMappedMerge(String ver) throws Exception {
        Process p = Runtime.getRuntime().exec(getCommandLine(new String[] {"git", "format-patch", "--stdout", "-1", "-k", ver}));
        BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
        
        File outputFile = File.createTempFile("merge", ".patch");
        outputFile.deleteOnExit();
        BufferedWriter writer = new BufferedWriter(new FileWriter(outputFile));
        
        String line = reader.readLine();
        while (line != null) {
            if ((line.startsWith("--- ")
                || line.startsWith("+++ ")) && line.length() > 7) {
                String file = line.substring(6).trim();
                for (ToFrom ent : pathMaps) {
                    if (file.contains(ent.from)) {
                        String newf = file.replace(ent.from, ent.to);
                        File fo = new File(newf);                        
                        if (fo.exists() && fo.isFile()) {
                            line = line.substring(0, 6) + newf;
                            break;
                        }
                    }
                }
                //System.out.println("newl: " + line);
            }
            writer.append(line);
            writer.newLine();
            line = reader.readLine();
        }
        waitFor(p, false);
        writer.flush();
        writer.close();
        
        p = Runtime.getRuntime().exec(getCommandLine(new String[] {"git", "am", "-k", outputFile.getCanonicalPath()}));
        
        if (waitFor(p, false) != 0) {
            p = Runtime.getRuntime().exec(getCommandLine(new String[] {"git", "status"}));
            runProcess(p);
                
            if (doCommit()) {
                records.add("M " + ver);
            }
        } else {
            records.add("M " + ver);
        }
        outputFile.delete();
    }
    private static String getPatchId(String id) throws Exception {
       
        String commands[] = new String[] { "git", "show", id};
        Process p = Runtime.getRuntime().exec(commands);
        InputStream in = p.getInputStream();
        
        commands = new String[] { "git", "patch-id"};
        Process p2 = Runtime.getRuntime().exec(commands);
        OutputStream out = p2.getOutputStream();
        byte bytes[] = new byte[1024];
        int len = in.read(bytes);
        BufferedReader r2 = new BufferedReader(new InputStreamReader(p2.getInputStream()));
        while (len > 0) {
            out.write(bytes, 0, len);
            len = in.read(bytes);
        }
        p.waitFor();
        out.close();
        
        id = r2.readLine();
        p2.waitFor();
        
        id = id.substring(0, id.indexOf(" "));
        return id;
    }
    
    private static String getUserName() throws Exception {
        BufferedReader reader;
        String line;
        Process p = Runtime.getRuntime().exec(new String[] {"git", "config", "user.name"});

        reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
        line = reader.readLine();
        p.waitFor();
        return line;
    }
    
    public static void main(String a[]) throws Exception {
        File file = new File(".git-commit-message.txt");
        if (file.exists()) {
            //make sure we delete this to not cause confusion
            file.delete();
        }
        
        System.out.println("Updating directory");

        doUpdate();
        
        List<String> args = new LinkedList<String>(Arrays.asList(a));
        List<String> check = new LinkedList<String>();
        while (!args.isEmpty()) {
            String get = args.remove(0);
            
            if ("-auto".equals(get)) { 
                auto = true;
            } else if ("-me".equals(get)) {
                username = getUserName();
            } else if ("-user".equals(get)) {
                username = args.get(0);
            } else {
                check.add(get);
            }
        }

        
        List<String> verList = getAvailableUpdates();
        if (!check.isEmpty()) {
            List<String> newList = new LinkedList<String>();
            for (String s : check) {
                if (verList.contains(s)) {
                    newList.add(s);
                }
            }
            verList = newList;
        }
        if (verList.isEmpty()) {
            System.out.println("Nothing needs to be merged");
            System.exit(0);
        }

        System.out.println("Merging versions (" + verList.size() + "): " + verList);

        List<String[]> gitLogs = null;
        //with GIT, we can relatively quickly check the logs on the current branch 
        //and compare with what should be merged and check if things are already merged
        gitLogs = getGitLogs();
        
        Set<String> jiras = new TreeSet<String>();

        for (int cur = 0; cur < verList.size(); cur++) {
            jiras.clear();
            String ver = verList.get(cur);
            String[] logLines = getLog(ver, jiras);
            if (logLines.length > 1
                && username != null
                && !logLines[0].contains(username)) {
                continue;
            }
            System.out.println();
            System.out.println("Merging: " + ver + " (" + (cur + 1) + "/" + verList.size() + ")");
            //System.out.println("http://svn.apache.org/viewvc?view=revision&revision=" + ver);
            
            for (String s : jiras) {
                System.out.println("https://issues.apache.org/jira/browse/" + s);
            }
            StringBuilder log = new StringBuilder();
            if (isBlocked(logLines)) {
                records.add("B " + ver);
                continue;
            }
            for (String s : logLines) {
                System.out.println(s);
                log.append(s).append("\n");
            }
            
            char c = auto ? 'M' : 0;
            if (checkPatchId(ver)) {
                continue;
            }
            if (checkAlreadyMerged(ver, gitLogs, logLines)) {
                c = 'R';
            }

            while (System.in.available() > 0) {
                System.in.read();
            }
            while (c != 'M'
                   && c != 'A'
                   && c != 'B'
                   && c != 'I'
                   && c != 'R'
                   && c != 'F'
                   && c != 'C'
                   && c != 'P') {
                System.out.print("[M]erge, [A]dvancedMerge, [B]lock, or [I]gnore, [R]ecord only, [F]lush, [C]hanges? ");
                int i = System.in.read();
                c = Character.toUpperCase((char)i);
            }

            switch (c) {
            case 'M':
                doMerge(ver);
                break;
            case 'A':
                doMappedMerge(ver);
                break;
            case 'P':
                System.out.println("Patch Id: " + getPatchId(ver));
                cur--;
                break;
            case 'B':
                records.add("B " + ver);
                break;
            case 'R':
                records.add("M " + ver);
                break;
            case 'F':
                flush();
                cur--;
                break;
            case 'C':
                changes(ver);
                cur--;
                break;
            case 'I':
                System.out.println("Ignoring");
                break;
            }
        }
        flush();
    }
    private static boolean isBlocked(String[] logLines) {
        for (String s: logLines) {
            if (s.trim().contains("Recording .gitmergeinfo Changes")) {
                return true;
            }
            if (s.contains("[maven-release-plugin] prepare")) {
                return true;
            }
        }
        return false;
    }
    private static boolean checkPatchId(String ver) throws Exception {
        if (!patchIds.isEmpty()) {
            String pid = getPatchId(ver);
            if (patchIds.contains("B " + pid)) {
                records.add("B " + ver);
                System.out.println("Already blocked: " + ver);
                return true;
            } else if (patchIds.contains("M " + pid)) {
                records.add("M " + ver);
                System.out.println("Already merged: " + ver);
                return true;
            }
        }
        return false;
    }
    private static boolean checkAlreadyMerged(String ver, List<String[]> gitLogs, String[] logLines) throws Exception {
        if (gitLogs == null) {
            return false;
        }
        List<List<String>> matchingLogs = new LinkedList<List<String>>();
        for (String[] f : gitLogs) {
            List<String> ll = compareLogs(f, logLines);
            if (!ll.isEmpty()) {
                matchingLogs.add(ll);
            }
        }
        
        if (!matchingLogs.isEmpty()) {
            //everything in the source log is in a log on this branch, let's prompt to record the merge
            System.out.println("Found possible commit(s) already on branch:");
            for (List<String> f : matchingLogs) {
                for (String s : f) {
                    System.out.println("    " + s);
                }
                System.out.println("------------------------");
            }
            
            while (System.in.available() > 0) {
                System.in.read();
            }
            char c = 0;
            while (c != 'Y'
                   && c != 'N') {
                System.out.print("Record as merged [Y/N]? ");
                int i = System.in.read();
                c = Character.toUpperCase((char)i);
            }
            if (c == 'Y') {
                return true;
            }
        }
        return false;
    }        
    private static List<String> compareLogs(String[] f, String[] logLines) throws IOException {
        ArrayList<String> onBranch = new ArrayList<String>(f.length);
        for (String s : f) {
            if (s.trim().startsWith("Conflicts:")) {
                break;
            }
            if (s.trim().length() > 0 
                && s.charAt(0) == ' '
                && !s.contains("git-svn-id")) {
                onBranch.add(s.trim());
            }
        }
        
        List<String> ll = new ArrayList<String>();
        for (String s : logLines) {
            if (s.trim().length() > 0 
                && onBranch.remove(s.trim())
                && !s.startsWith("Author: ")
                && !s.startsWith("Date: ")
                && !s.contains("git-svn-id")) {                
                ll.add(s);
            } 
        }
        return ll;
    }
        

    private static String[] getCommandLine(String[] args) {
        List<String> argLine = new ArrayList<String>();
        if (isWindows()) {
            argLine.add("cmd.exe");
            argLine.add("/c");
        }

        argLine.addAll(Arrays.asList(args));
        StringBuilder b = new StringBuilder(256);
        for (String s : argLine) {
            if (b.length() == 0) {
                b.append("Running \"");
            } else {
                b.append(" ");
            }
            b.append(s);
        }
        b.append("\"...");
        System.out.println(b.toString());
        return argLine.toArray(new String[argLine.size()]);
    }

    private static boolean isWindows() {
        return System.getProperty("os.name").toLowerCase().indexOf("windows") != -1;
    }
    
    
}


