using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

namespace Google.ProtocolBuffers.ProtoGen
{
    /// <summary>
    /// Preprocesses any input files with an extension of '.proto' by running protoc.exe.  If arguments
    /// are supplied with '--' prefix they are provided to protoc.exe, otherwise they are assumed to
    /// be used for ProtoGen.exe which is run on the resulting output proto buffer.  If the option
    /// --descriptor_set_out= is specified the proto buffer file is kept, otherwise it will be removed
    /// after code generation.
    /// </summary>
    public class ProgramPreprocess
    {
        private const string ProtocExecutable = "protoc.exe";
        private const string ProtocDirectoryArg = "--protoc_dir=";

        private static int Main(string[] args)
        {
            try
            {
                return Environment.ExitCode = Run(args);
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex);
                return Environment.ExitCode = 2;
            }
        }

        public static int Run(params string[] args)
        {
            bool deleteFile = false;
            string tempFile = null;
            int result;
            bool doHelp = args.Length == 0;
            try
            {
                List<string> protocArgs = new List<string>();
                List<string> protoGenArgs = new List<string>();

                string protocFile = GuessProtocFile(args);

                foreach (string arg in args)
                {
                    doHelp |= StringComparer.OrdinalIgnoreCase.Equals(arg, "/?");
                    doHelp |= StringComparer.OrdinalIgnoreCase.Equals(arg, "/help");
                    doHelp |= StringComparer.OrdinalIgnoreCase.Equals(arg, "-?");
                    doHelp |= StringComparer.OrdinalIgnoreCase.Equals(arg, "-help");

                    if (arg.StartsWith("--descriptor_set_out="))
                    {
                        tempFile = arg.Substring("--descriptor_set_out=".Length);
                        protoGenArgs.Add(tempFile);
                    }
                }

                if (doHelp)
                {
                    Console.WriteLine();
                    Console.WriteLine("PROTOC.exe: Use any of the following options that begin with '--':");
                    Console.WriteLine();
                    try
                    {
                        RunProtoc(protocFile, "--help");
                    }
                    catch (Exception ex)
                    {
                        Console.Error.WriteLine(ex.Message);
                    }
                    Console.WriteLine();
                    Console.WriteLine();
                    Console.WriteLine(
                        "PROTOGEN.exe: The following options are used to specify defaults for code generation.");
                    Console.WriteLine();
                    Program.Main(new string[0]);
                    Console.WriteLine();
                    Console.WriteLine("The following option enables PROTOGEN.exe to find PROTOC.exe");
                    Console.WriteLine("{0}<directory containing protoc.exe>", ProtocDirectoryArg);
                    return 0;
                }

                string pathRoot = Environment.CurrentDirectory;
                foreach(string arg in args)
                {
                    if (arg.StartsWith("--proto_path=", StringComparison.InvariantCultureIgnoreCase))
                    {
                        pathRoot = arg.Substring(13);
                    }
                }

                foreach (string arg in args)
                {
                    if (arg.StartsWith(ProtocDirectoryArg))
                    {
                        // Handled earlier
                        continue;
                    }
                    if (arg.StartsWith("--"))
                    {
                        protocArgs.Add(arg);
                    }
                    else if ((File.Exists(arg) || File.Exists(Path.Combine(pathRoot, arg))) &&
                             StringComparer.OrdinalIgnoreCase.Equals(".proto", Path.GetExtension(arg)))
                    {
                        if (tempFile == null)
                        {
                            deleteFile = true;
                            tempFile = Path.GetTempFileName();
                            protocArgs.Add(String.Format("--descriptor_set_out={0}", tempFile));
                            protoGenArgs.Add(tempFile);
                        }
                        string patharg = arg;
                        if (!File.Exists(patharg))
                        {
                            patharg = Path.Combine(pathRoot, arg);
                        }

                        protocArgs.Add(patharg);
                    }
                    else
                    {
                        protoGenArgs.Add(arg);
                    }
                }

                if (tempFile != null)
                {
                    result = RunProtoc(protocFile, protocArgs.ToArray());
                    if (result != 0)
                    {
                        return result;
                    }
                }

                result = Program.Main(protoGenArgs.ToArray());
            }
            finally
            {
                if (deleteFile && tempFile != null && File.Exists(tempFile))
                {
                    File.Delete(tempFile);
                }
            }
            return result;
        }

        /// <summary>
        /// Tries to work out where protoc is based on command line arguments, the current
        /// directory, the directory containing protogen, and the path.
        /// </summary>
        /// <returns>The path to protoc.exe, or null if it can't be found.</returns>
        private static string GuessProtocFile(params string[] args)
        {
            // Why oh why is this not in System.IO.Path or Environment...?
            List<string> searchPath = new List<string>();
            foreach (string arg in args)
            {
                if (arg.StartsWith("--protoc_dir="))
                {
                    searchPath.Add(arg.Substring(ProtocDirectoryArg.Length));
                }
            }
            searchPath.Add(Environment.CurrentDirectory);
            searchPath.Add(AppDomain.CurrentDomain.BaseDirectory);
            searchPath.AddRange((Environment.GetEnvironmentVariable("PATH") ?? String.Empty).Split(Path.PathSeparator));

            foreach (string path in searchPath)
            {
                string exeFile = Path.Combine(path, ProtocExecutable);
                if (File.Exists(exeFile))
                {
                    return exeFile;
                }
            }
            return null;
        }

        private static int RunProtoc(string exeFile, params string[] args)
        {
            if (exeFile == null)
            {
                throw new FileNotFoundException(
                    "Unable to locate " + ProtocExecutable +
                    " make sure it is in the PATH, cwd, or exe dir, or use --protoc_dir=...");
            }

            ProcessStartInfo psi = new ProcessStartInfo(exeFile);
            psi.Arguments = EscapeArguments(args);
            psi.RedirectStandardError = true;
            psi.RedirectStandardInput = false;
            psi.RedirectStandardOutput = true;
            psi.ErrorDialog = false;
            psi.CreateNoWindow = true;
            psi.UseShellExecute = false;
            psi.WorkingDirectory = Environment.CurrentDirectory;

            Process process = Process.Start(psi);
            if (process == null)
            {
                return 1;
            }

            process.WaitForExit();

            string tmp = process.StandardOutput.ReadToEnd();
            if (tmp.Trim().Length > 0)
            {
                Console.Out.WriteLine(tmp);
            }
            tmp = process.StandardError.ReadToEnd();
            if (tmp.Trim().Length > 0)
            {
                // Replace protoc output with something more amenable to Visual Studio.
                var regexMsvs = new Regex(@"(.*)\((\d+)\).* column=(\d+)\s*:\s*(.*)");
                tmp = regexMsvs.Replace(tmp, "$1($2,$3): error CS9999: $4");
                var regexGcc = new Regex(@"(.*):(\d+):(\d+):\s*(.*)");
                tmp = regexGcc.Replace(tmp, "$1($2,$3): error CS9999: $4");
                Console.Error.WriteLine(tmp);
            }
            return process.ExitCode;
        }

        /// <summary>
        /// Quotes all arguments that contain whitespace, or begin with a quote and returns a single
        /// argument string for use with Process.Start().
        /// </summary>
        /// <remarks>http://csharptest.net/?p=529</remarks>
        /// <param name="args">A list of strings for arguments, may not contain null, '\0', '\r', or '\n'</param>
        /// <returns>The combined list of escaped/quoted strings</returns>
        /// <exception cref="System.ArgumentNullException">Raised when one of the arguments is null</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">Raised if an argument contains '\0', '\r', or '\n'</exception>
        public static string EscapeArguments(params string[] args)
        {
            StringBuilder arguments = new StringBuilder();
            Regex invalidChar = new Regex("[\x00\x0a\x0d]");//  these can not be escaped
            Regex needsQuotes = new Regex(@"\s|""");//          contains whitespace or two quote characters
            Regex escapeQuote = new Regex(@"(\\*)(""|$)");//    one or more '\' followed with a quote or end of string
            for (int carg = 0; args != null && carg < args.Length; carg++)
            {
                if (args[carg] == null)
                {
                    throw new ArgumentNullException("args[" + carg + "]");
                }
                if (invalidChar.IsMatch(args[carg]))
                {
                    throw new ArgumentOutOfRangeException("args[" + carg + "]");
                }
                if (args[carg] == String.Empty)
                {
                    arguments.Append("\"\"");
                }
                else if (!needsQuotes.IsMatch(args[carg])) { arguments.Append(args[carg]); }
                else
                {
                    arguments.Append('"');
                    arguments.Append(escapeQuote.Replace(args[carg],
                                                         m =>
                                                         m.Groups[1].Value + m.Groups[1].Value +
                                                         (m.Groups[2].Value == "\"" ? "\\\"" : "")
                                         ));
                    arguments.Append('"');
                }
                if (carg + 1 < args.Length)
                {
                    arguments.Append(' ');
                }
            }
            return arguments.ToString();
        }
    }
}