<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<!-- GRPC CODE GENERATION TARGETS FOR MSBUILD -->
<Project>
  <ItemGroup>
    <PackageReference Include="RoslynCodeTaskFactory" Version="2.0.7" />
  </ItemGroup>
  <UsingTask TaskName="GrpcToCSharp" TaskFactory="CodeTaskFactory" AssemblyFile="$(RoslynCodeTaskFactory)" Condition=" '$(RoslynCodeTaskFactory)' != '' ">
    <ParameterGroup>
      <!-- The directory where the project is located. This is typically $(ProjectDir) -->
      <OutputDirectory ParameterType="System.String" Required="true" />
      <!-- This is the list of C# target files to be generaterd. This is typically @(Compile) -->
      <SourceFileList ParameterType="System.String" Required="true" />
      <!-- The directory where the .avsc schema files are located. -->
      <GrpcSchemaDirectory ParameterType="System.String" Required="true" />
      <!-- The where gRPC schema generator and dependent libraries are located. -->
      <GrpcBinaryDirectory ParameterType="System.String" Required="true" />
      <!-- gRPC tools extension e.g., .exe for windows. -->
      <GrpcToolsExtension ParameterType="System.String" Required="false" />
    </ParameterGroup>
    <Task>
      <Using Namespace="System" />
      <Using Namespace="System.IO" />
      <Using Namespace="System.Diagnostics" />
      <Using Namespace="System.Threading" />
      <Using Namespace="System.Threading.Tasks" />
      <Code Type="Fragment" Language="C#">
        <![CDATA[
          // Create a temporary working directory for the log file.
          string tempDir = Path.GetFullPath(Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()));
          Directory.CreateDirectory(tempDir);

          var grpcCSharpPlugin = "grpc_csharp_plugin";
          var protocExe = "protoc";
          if (GrpcToolsExtension != null)
          {
            grpcCSharpPlugin += GrpcToolsExtension;
            protocExe += GrpcToolsExtension;
          }
          // Get the full path to the directory where the gRPC .proto files are located.
          string grpcSrcFileDirectory = Path.GetFullPath(GrpcSchemaDirectory);
          string grpcToolsDirectory = Path.GetFullPath(GrpcBinaryDirectory);
          string grpcOutputDirectory = Path.GetFullPath(OutputDirectory);
          string grpcPluginName = Path.Combine(GrpcBinaryDirectory, grpcCSharpPlugin);

          Directory.CreateDirectory(grpcOutputDirectory);
           
          // Get the list of names of .proto files
          string[] sourceFiles = SourceFileList.Split(';');

          // Setup the conversion process.
          ProcessStartInfo rProcInfo = new ProcessStartInfo()
          {
              RedirectStandardOutput = true,
              RedirectStandardError = true,
              UseShellExecute = false,
              CreateNoWindow = true,
              FileName = Path.Combine(grpcToolsDirectory, protocExe)
          };

          bool conversionError = false;
          using (StreamWriter logWriter = new StreamWriter(Path.Combine(tempDir, "GrpcCodeGeneration.log")))
          {
              foreach (string file in sourceFiles)
              {
                  logWriter.WriteLine("Processing file: {0}", file);
                  Console.WriteLine("Processing file: {0}", file);
				  string fullFileName = Path.Combine(grpcSrcFileDirectory, file);
                  if (File.Exists(fullFileName))
                  {
                    rProcInfo.Arguments = " -I" + grpcSrcFileDirectory + " --csharp_out " + grpcOutputDirectory
                        + " " + fullFileName + " --grpc_out " + grpcOutputDirectory
                        + " --plugin=protoc-gen-grpc=" + grpcPluginName;
                    logWriter.WriteLine("Command: {0}", rProcInfo.Arguments);
                    StringBuilder stdOutBuilder = new StringBuilder();
                    StringBuilder stdErrBuilder = new StringBuilder();
                    using (Process rProc = Process.Start(rProcInfo))
                    {
                      var stdOutTask = System.Threading.Tasks.Task.Run(
                        () => stdOutBuilder.Append(rProc.StandardOutput.ReadToEnd()));
                      var stdErrTask = System.Threading.Tasks.Task.Run(
                        () => stdErrBuilder.Append(rProc.StandardError.ReadToEnd()));
                      rProc.WaitForExit();
                      conversionError = rProc.ExitCode != 0;
                      // Wait for std out and error readers.
                      stdOutTask.Wait();
                      stdErrTask.Wait();
                    }
                    logWriter.WriteLine("[StdOut]:");
                    logWriter.WriteLine(stdOutBuilder.ToString());
                    logWriter.WriteLine("[StdErr]:");
                    logWriter.WriteLine(stdErrBuilder.ToString());
                  }
              }
          }
          if (!conversionError)
          {
            Directory.Delete(tempDir, recursive : true);
          }
      ]]>
      </Code>
    </Task>
  </UsingTask>
</Project>