#region Copyright notice and license

// Copyright 2018 gRPC authors.
//
// 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.

#endregion

using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

namespace Grpc.Tools
{
    /// <summary>
    /// Run Google proto compiler (protoc).
    ///
    /// After a successful run, the task reads the dependency file if specified
    /// to be saved by the compiler, and returns its output files.
    ///
    /// This task (unlike PrepareProtoCompile) does not attempt to guess anything
    /// about language-specific behavior of protoc, and therefore can be used for
    /// any language outputs.
    /// </summary>
    public class ProtoCompile : ToolTask
    {
        /*

        Usage: /home/kkm/work/protobuf/src/.libs/lt-protoc [OPTION] PROTO_FILES
        Parse PROTO_FILES and generate output based on the options given:
          -IPATH, --proto_path=PATH   Specify the directory in which to search for
                                      imports.  May be specified multiple times;
                                      directories will be searched in order.  If not
                                      given, the current working directory is used.
          --version                   Show version info and exit.
          -h, --help                  Show this text and exit.
          --encode=MESSAGE_TYPE       Read a text-format message of the given type
                                      from standard input and write it in binary
                                      to standard output.  The message type must
                                      be defined in PROTO_FILES or their imports.
          --decode=MESSAGE_TYPE       Read a binary message of the given type from
                                      standard input and write it in text format
                                      to standard output.  The message type must
                                      be defined in PROTO_FILES or their imports.
          --decode_raw                Read an arbitrary protocol message from
                                      standard input and write the raw tag/value
                                      pairs in text format to standard output.  No
                                      PROTO_FILES should be given when using this
                                      flag.
          --descriptor_set_in=FILES   Specifies a delimited list of FILES
                                      each containing a FileDescriptorSet (a
                                      protocol buffer defined in descriptor.proto).
                                      The FileDescriptor for each of the PROTO_FILES
                                      provided will be loaded from these
                                      FileDescriptorSets. If a FileDescriptor
                                      appears multiple times, the first occurrence
                                      will be used.
          -oFILE,                     Writes a FileDescriptorSet (a protocol buffer,
            --descriptor_set_out=FILE defined in descriptor.proto) containing all of
                                      the input files to FILE.
          --include_imports           When using --descriptor_set_out, also include
                                      all dependencies of the input files in the
                                      set, so that the set is self-contained.
          --include_source_info       When using --descriptor_set_out, do not strip
                                      SourceCodeInfo from the FileDescriptorProto.
                                      This results in vastly larger descriptors that
                                      include information about the original
                                      location of each decl in the source file as
                                      well as surrounding comments.
          --dependency_out=FILE       Write a dependency output file in the format
                                      expected by make. This writes the transitive
                                      set of input file paths to FILE
          --error_format=FORMAT       Set the format in which to print errors.
                                      FORMAT may be 'gcc' (the default) or 'msvs'
                                      (Microsoft Visual Studio format).
          --print_free_field_numbers  Print the free field numbers of the messages
                                      defined in the given proto files. Groups share
                                      the same field number space with the parent
                                      message. Extension ranges are counted as
                                      occupied fields numbers.

          --plugin=EXECUTABLE         Specifies a plugin executable to use.
                                      Normally, protoc searches the PATH for
                                      plugins, but you may specify additional
                                      executables not in the path using this flag.
                                      Additionally, EXECUTABLE may be of the form
                                      NAME=PATH, in which case the given plugin name
                                      is mapped to the given executable even if
                                      the executable's own name differs.
          --cpp_out=OUT_DIR           Generate C++ header and source.
          --csharp_out=OUT_DIR        Generate C# source file.
          --java_out=OUT_DIR          Generate Java source file.
          --javanano_out=OUT_DIR      Generate Java Nano source file.
          --js_out=OUT_DIR            Generate JavaScript source.
          --objc_out=OUT_DIR          Generate Objective C header and source.
          --php_out=OUT_DIR           Generate PHP source file.
          --python_out=OUT_DIR        Generate Python source file.
          --ruby_out=OUT_DIR          Generate Ruby source file.
          @<filename>                 Read options and filenames from file. If a
                                      relative file path is specified, the file
                                      will be searched in the working directory.
                                      The --proto_path option will not affect how
                                      this argument file is searched. Content of
                                      the file will be expanded in the position of
                                      @<filename> as in the argument list. Note
                                      that shell expansion is not applied to the
                                      content of the file (i.e., you cannot use
                                      quotes, wildcards, escapes, commands, etc.).
                                      Each line corresponds to a single argument,
                                      even if it contains spaces.
        */
        static string[] s_supportedGenerators = new[] { "cpp", "csharp", "java",
                                                        "javanano", "js", "objc",
                                                        "php", "python", "ruby" };

        static readonly TimeSpan s_regexTimeout = TimeSpan.FromSeconds(1);

        static readonly List<ErrorListFilter> s_errorListFilters = new List<ErrorListFilter>()
        {
            // Example warning with location
            //../Protos/greet.proto(19) : warning in column=5 : warning : When enum name is stripped and label is PascalCased (Zero),
            // this value label conflicts with Zero. This will make the proto fail to compile for some languages, such as C#.
            new ErrorListFilter
            {
                Pattern = new Regex(
                    pattern: "^(?'FILENAME'.+?)\\((?'LINE'\\d+)\\) ?: ?warning in column=(?'COLUMN'\\d+) ?: ?(?'TEXT'.*)",
                    options: RegexOptions.Compiled | RegexOptions.IgnoreCase,
                    matchTimeout: s_regexTimeout),
                LogAction = (log, match) =>
                {
                    int.TryParse(match.Groups["LINE"].Value, out var line);
                    int.TryParse(match.Groups["COLUMN"].Value, out var column);

                    log.LogWarning(
                        subcategory: null,
                        warningCode: null,
                        helpKeyword: null,
                        file: match.Groups["FILENAME"].Value,
                        lineNumber: line,
                        columnNumber: column,
                        endLineNumber: 0,
                        endColumnNumber: 0,
                        message: match.Groups["TEXT"].Value);
                }
            },

            // Example error with location
            //../Protos/greet.proto(14) : error in column=10: "name" is already defined in "Greet.HelloRequest".
            new ErrorListFilter
            {
                Pattern = new Regex(
                    pattern: "^(?'FILENAME'.+?)\\((?'LINE'\\d+)\\) ?: ?error in column=(?'COLUMN'\\d+) ?: ?(?'TEXT'.*)",
                    options: RegexOptions.Compiled | RegexOptions.IgnoreCase,
                    matchTimeout: s_regexTimeout),
                LogAction = (log, match) =>
                {
                    int.TryParse(match.Groups["LINE"].Value, out var line);
                    int.TryParse(match.Groups["COLUMN"].Value, out var column);

                    log.LogError(
                        subcategory: null,
                        errorCode: null,
                        helpKeyword: null,
                        file: match.Groups["FILENAME"].Value,
                        lineNumber: line,
                        columnNumber: column,
                        endLineNumber: 0,
                        endColumnNumber: 0,
                        message: match.Groups["TEXT"].Value);
                }
            },

            // Example warning without location
            //../Protos/greet.proto: warning: Import google/protobuf/empty.proto but not used.
            new ErrorListFilter
            {
                Pattern = new Regex(
                    pattern: "^(?'FILENAME'.+?): ?warning: ?(?'TEXT'.*)",
                    options: RegexOptions.Compiled | RegexOptions.IgnoreCase,
                    matchTimeout: s_regexTimeout),
                LogAction = (log, match) =>
                {
                    log.LogWarning(
                        subcategory: null,
                        warningCode: null,
                        helpKeyword: null,
                        file: match.Groups["FILENAME"].Value,
                        lineNumber: 0,
                        columnNumber: 0,
                        endLineNumber: 0,
                        endColumnNumber: 0,
                        message: match.Groups["TEXT"].Value);
                }
            },

            // Example warning from plugins that use GOOGLE_LOG
            // [libprotobuf WARNING T:\altsrc\..\csharp_enum.cc:74] Duplicate enum value Work (originally Work) in PhoneType; adding underscore to distinguish
            new ErrorListFilter
            {
                Pattern = new Regex(
                    pattern: "^\\[.+? WARNING (?'FILENAME'.+?):(?'LINE'\\d+?)\\] ?(?'TEXT'.*)",
                    options: RegexOptions.Compiled | RegexOptions.IgnoreCase,
                    matchTimeout: s_regexTimeout),
                LogAction = (log, match) =>
                {
                    // The filename and line logged by the plugins may not be useful to the
                    // end user as they are not the location in the proto file but rather
                    // in the source code for the plugin. Log them anyway as they may help in
                    // diagnostics.
                    int.TryParse(match.Groups["LINE"].Value, out var line);
                    log.LogWarning(
                        subcategory: null,
                        warningCode: null,
                        helpKeyword: null,
                        file: match.Groups["FILENAME"].Value,
                        lineNumber: line,
                        columnNumber: 0,
                        endLineNumber: 0,
                        endColumnNumber: 0,
                        message: match.Groups["TEXT"].Value);
                }
            },

            // Example error from plugins that use GOOGLE_LOG
            // [libprotobuf ERROR T:\path\...\filename:23] Some message
            // [libprotobuf FATAL T:\path\...\filename:23] Some message
            new ErrorListFilter
            {
                Pattern = new Regex(
                    pattern: "^\\[.+? (?'LEVEL'ERROR|FATAL) (?'FILENAME'.+?):(?'LINE'\\d+?)\\] ?(?'TEXT'.*)",
                    options: RegexOptions.Compiled | RegexOptions.IgnoreCase,
                    matchTimeout: s_regexTimeout),
                LogAction = (log, match) =>
                {
                    // The filename and line logged by the plugins may not be useful to the
                    // end user as they are not the location in the proto file but rather
                    // in the source code for the plugin. Log them anyway as they may help in
                    // diagnostics.
                    int.TryParse(match.Groups["LINE"].Value, out var line);
                    log.LogError(
                        subcategory: null,
                        errorCode: null,
                        helpKeyword: null,
                        file: match.Groups["FILENAME"].Value,
                        lineNumber: line,
                        columnNumber: 0,
                        endLineNumber: 0,
                        endColumnNumber: 0,
                        message: match.Groups["LEVEL"].Value + " " + match.Groups["TEXT"].Value);
                }
            },

            // Example error without location
            //../Protos/greet.proto: Import "google/protobuf/empty.proto" was listed twice.
            new ErrorListFilter
            {
                Pattern = new Regex(
                    pattern: "^(?'FILENAME'.+?): ?(?'TEXT'.*)",
                    options: RegexOptions.Compiled | RegexOptions.IgnoreCase,
                    matchTimeout: s_regexTimeout),
                LogAction = (log, match) =>
                {
                    log.LogError(
                        subcategory: null,
                        errorCode: null,
                        helpKeyword: null,
                        file: match.Groups["FILENAME"].Value,
                        lineNumber: 0,
                        columnNumber: 0,
                        endLineNumber: 0,
                        endColumnNumber: 0,
                        message: match.Groups["TEXT"].Value);
                }
            }
        };

        /// <summary>
        /// Code generator.
        /// </summary>
        [Required]
        public string Generator { get; set; }

        /// <summary>
        /// Protobuf files to compile.
        /// </summary>
        [Required]
        public ITaskItem[] Protobuf { get; set; }

        /// <summary>
        /// Directory where protoc dependency files are cached. If provided, dependency
        /// output filename is autogenerated from source directory hash and file name.
        /// Mutually exclusive with DependencyOut.
        /// Switch: --dependency_out (with autogenerated file name).
        /// </summary>
        public string ProtoDepDir { get; set; }

        /// <summary>
        /// Dependency file full name. Mutually exclusive with ProtoDepDir.
        /// Autogenerated file name is available in this property after execution.
        /// Switch: --dependency_out.
        /// </summary>
        [Output]
        public string DependencyOut { get; set; }

        /// <summary>
        /// The directories to search for imports. Directories will be searched
        /// in order. If not given, the current working directory is used.
        /// Switch: --proto_path.
        /// </summary>
        public string[] ProtoPath { get; set; }

        /// <summary>
        /// Generated code directory. The generator property determines the language.
        /// Switch: --GEN_out= (for different generators GEN, e.g. --csharp_out).
        /// </summary>
        [Required]
        public string OutputDir { get; set; }

        /// <summary>
        /// Codegen options. See also OptionsFromMetadata.
        /// Switch: --GEN_opt= (for different generators GEN, e.g. --csharp_opt).
        /// </summary>
        public string[] OutputOptions { get; set; }

        /// <summary>
        /// Additional arguments that will be passed unmodified to protoc (and before any file names).
        /// For example, "--experimental_allow_proto3_optional"
        /// </summary>
        public string[] AdditionalProtocArguments { get; set; }

        /// <summary>
        /// Full path to the gRPC plugin executable. If specified, gRPC generation
        /// is enabled for the files.
        /// Switch: --plugin=protoc-gen-grpc=
        /// </summary>
        public string GrpcPluginExe { get; set; }

        /// <summary>
        /// Generated gRPC  directory. The generator property determines the
        /// language. If gRPC is enabled but this is not given, OutputDir is used.
        /// Switch: --grpc_out=
        /// </summary>
        public string GrpcOutputDir { get; set; }

        /// <summary>
        /// gRPC Codegen options. See also OptionsFromMetadata.
        /// --grpc_opt=opt1,opt2=val (comma-separated).
        /// </summary>
        public string[] GrpcOutputOptions { get; set; }

        /// <summary>
        /// List of files written in addition to generated outputs. Includes a
        /// single item for the dependency file if written.
        /// </summary>
        [Output]
        public ITaskItem[] AdditionalFileWrites { get; private set; }

        /// <summary>
        /// List of language files generated by protoc. Empty unless DependencyOut
        /// or ProtoDepDir is set, since the file writes are extracted from protoc
        /// dependency output file.
        /// </summary>
        [Output]
        public ITaskItem[] GeneratedFiles { get; private set; }

        // Hide this property from MSBuild, we should never use a shell script.
        private new bool UseCommandProcessor { get; set; }

        protected override string ToolName => Platform.IsWindows ? "protoc.exe" : "protoc";

        // Since we never try to really locate protoc.exe somehow, just try ToolExe
        // as the full tool location. It will be either just protoc[.exe] from
        // ToolName above if not set by the user, or a user-supplied full path. The
        // base class will then resolve the former using system PATH.
        protected override string GenerateFullPathToTool() => ToolExe;

        // Log protoc errors with the High priority (bold white in MsBuild,
        // printed with -v:n, and shown in the Output windows in VS).
        protected override MessageImportance StandardErrorLoggingImportance => MessageImportance.High;

        // Called by base class to validate arguments and make them consistent.
        protected override bool ValidateParameters()
        {
            // Part of proto command line switches, must be lowercased.
            Generator = Generator.ToLowerInvariant();
            if (!System.Array.Exists(s_supportedGenerators, g => g == Generator))
            {
                Log.LogError("Invalid value for Generator='{0}'. Supported generators: {1}",
                             Generator, string.Join(", ", s_supportedGenerators));
            }

            if (ProtoDepDir != null && DependencyOut != null)
            {
                Log.LogError("Properties ProtoDepDir and DependencyOut may not be both specified");
            }

            if (Protobuf.Length > 1 && (ProtoDepDir != null || DependencyOut != null))
            {
                Log.LogError("Proto compiler currently allows only one input when " +
                             "--dependency_out is specified (via ProtoDepDir or DependencyOut). " +
                             "Tracking issue: https://github.com/protocolbuffers/protobuf/pull/3959");
            }

            // Use ProtoDepDir to autogenerate DependencyOut
            if (ProtoDepDir != null)
            {
                DependencyOut = DepFileUtil.GetDepFilenameForProto(ProtoDepDir, Protobuf[0].ItemSpec);
            }

            if (GrpcPluginExe == null)
            {
                GrpcOutputOptions = null;
                GrpcOutputDir = null;
            }
            else if (GrpcOutputDir == null)
            {
                // Use OutputDir for gRPC output if not specified otherwise by user.
                GrpcOutputDir = OutputDir;
            }

            return !Log.HasLoggedErrors && base.ValidateParameters();
        }

        // Protoc chokes on BOM, naturally. I would!
        static readonly Encoding s_utf8WithoutBom = new UTF8Encoding(false);
        protected override Encoding ResponseFileEncoding => s_utf8WithoutBom;

        // Protoc takes one argument per line from the response file, and does not
        // require any quoting whatsoever. Otherwise, this is similar to the
        // standard CommandLineBuilder
        class ProtocResponseFileBuilder
        {
            StringBuilder _data = new StringBuilder(1000);
            public override string ToString() => _data.ToString();

            // If 'value' is not empty, append '--name=value\n'.
            public void AddSwitchMaybe(string name, string value)
            {
                if (!string.IsNullOrEmpty(value))
                {
                    _data.Append("--").Append(name).Append("=")
                         .Append(value).Append('\n');
                }
            }

            // Add switch with the 'values' separated by commas, for options.
            public void AddSwitchMaybe(string name, string[] values)
            {
                if (values?.Length > 0)
                {
                    _data.Append("--").Append(name).Append("=")
                         .Append(string.Join(",", values)).Append('\n');
                }
            }

            // Add a positional argument to the file data.
            public void AddArg(string arg)
            {
                _data.Append(arg).Append('\n');
            }
        };

        // Called by the base ToolTask to get response file contents.
        protected override string GenerateResponseFileCommands()
        {
            var cmd = new ProtocResponseFileBuilder();
            cmd.AddSwitchMaybe(Generator + "_out", TrimEndSlash(OutputDir));
            cmd.AddSwitchMaybe(Generator + "_opt", OutputOptions);
            cmd.AddSwitchMaybe("plugin=protoc-gen-grpc", GrpcPluginExe);
            cmd.AddSwitchMaybe("grpc_out", TrimEndSlash(GrpcOutputDir));
            cmd.AddSwitchMaybe("grpc_opt", GrpcOutputOptions);
            if (ProtoPath != null)
            {
                foreach (string path in ProtoPath)
                {
                    cmd.AddSwitchMaybe("proto_path", TrimEndSlash(path));
                }
            }
            cmd.AddSwitchMaybe("dependency_out", DependencyOut);
            cmd.AddSwitchMaybe("error_format", "msvs");

            if (AdditionalProtocArguments != null)
            {
                foreach (var additionalProtocOption in AdditionalProtocArguments)
                {
                    cmd.AddArg(additionalProtocOption);
                }
            }

            foreach (var proto in Protobuf)
            {
                cmd.AddArg(proto.ItemSpec);
            }
            return cmd.ToString();
        }

        // Protoc cannot digest trailing slashes in directory names,
        // curiously under Linux, but not in Windows.
        static string TrimEndSlash(string dir)
        {
            if (dir == null || dir.Length <= 1)
            {
                return dir;
            }
            string trim = dir.TrimEnd('/', '\\');
            // Do not trim the root slash, drive letter possible.
            if (trim.Length == 0)
            {
                // Slashes all the way down.
                return dir.Substring(0, 1);
            }
            if (trim.Length == 2 && dir.Length > 2 && trim[1] == ':')
            {
                // We have a drive letter and root, e. g. 'C:\'
                return dir.Substring(0, 3);
            }
            return trim;
        }

        // Called by the base class to log tool's command line.
        //
        // Protoc command file is peculiar, with one argument per line, separated
        // by newlines. Unwrap it for log readability into a single line, and also
        // quote arguments, lest it look weird and so it may be copied and pasted
        // into shell. Since this is for logging only, correct enough is correct.
        protected override void LogToolCommand(string cmd)
        {
            var printer = new StringBuilder(1024);

            // Print 'str' slice into 'printer', wrapping in quotes if contains some
            // interesting characters in file names, or if empty string. The list of
            // characters requiring quoting is not by any means exhaustive; we are
            // just striving to be nice, not guaranteeing to be nice.
            var quotable = new[] { ' ', '!', '$', '&', '\'', '^' };
            void PrintQuoting(string str, int start, int count)
            {
                bool wrap = count == 0 || str.IndexOfAny(quotable, start, count) >= 0;
                if (wrap) printer.Append('"');
                printer.Append(str, start, count);
                if (wrap) printer.Append('"');
            }

            for (int ib = 0, ie; (ie = cmd.IndexOf('\n', ib)) >= 0; ib = ie + 1)
            {
                // First line only contains both the program name and the first switch.
                // We can rely on at least the '--out_dir' switch being always present.
                if (ib == 0)
                {
                    int iep = cmd.IndexOf(" --");
                    if (iep > 0)
                    {
                        PrintQuoting(cmd, 0, iep);
                        ib = iep + 1;
                    }
                }
                printer.Append(' ');
                if (cmd[ib] == '-')
                {
                    // Print switch unquoted, including '=' if any.
                    int iarg = cmd.IndexOf('=', ib, ie - ib);
                    if (iarg < 0)
                    {
                        // Bare switch without a '='.
                        printer.Append(cmd, ib, ie - ib);
                        continue;
                    }
                    printer.Append(cmd, ib, iarg + 1 - ib);
                    ib = iarg + 1;
                }
                // A positional argument or switch value.
                PrintQuoting(cmd, ib, ie - ib);
            }

            base.LogToolCommand(printer.ToString());
        }

        protected override void LogEventsFromTextOutput(string singleLine, MessageImportance messageImportance)
        {
            foreach (ErrorListFilter filter in s_errorListFilters)
            {
                try
                {
                    Match match = filter.Pattern.Match(singleLine);

                    if (match.Success)
                    {
                        filter.LogAction(Log, match);
                        return;
                    }
                } catch (RegexMatchTimeoutException)
                {
                    Log.LogWarning("Unable to parse output from protoc. Regex timeout.");
                }
            }

            base.LogEventsFromTextOutput(singleLine, messageImportance);
        }

        // Main task entry point.
        public override bool Execute()
        {
            base.UseCommandProcessor = false;

            bool ok = base.Execute();
            if (!ok)
            {
                return false;
            }

            // Read dependency output file from the compiler to retrieve the
            // definitive list of created files. Report the dependency file
            // itself as having been written to.
            if (DependencyOut != null)
            {
                string[] outputs = DepFileUtil.ReadDependencyOutputs(DependencyOut, Log);
                if (HasLoggedErrors)
                {
                    return false;
                }

                GeneratedFiles = new ITaskItem[outputs.Length];
                for (int i = 0; i < outputs.Length; i++)
                {
                    GeneratedFiles[i] = new TaskItem(outputs[i]);
                }
                AdditionalFileWrites = new ITaskItem[] { new TaskItem(DependencyOut) };
            }

            return true;
        }

        class ErrorListFilter
        {
            public Regex Pattern { get; set; }
            public Action<TaskLoggingHelper, Match> LogAction { get; set; }
        }
    };
}
