<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <RepoRootDirectory>$(MSBuildThisFileDirectory)</RepoRootDirectory>
    <PkgDirectory>$(RepoRootDirectory)\pkg\</PkgDirectory>
    <TestsDirectory>$(RepoRootDirectory)\tests\</TestsDirectory>
    <SdkDirectory>$(RepoRootDirectory)\sdk\</SdkDirectory>
    <NodeJSSdkDirectory>$(SdkDirectory)\nodejs\</NodeJSSdkDirectory>
    <DotNetSdkDirectory>$(SdkDirectory)\dotnet\</DotNetSdkDirectory>
    <PythonSdkDirectory>$(SdkDirectory)\python\</PythonSdkDirectory>
    <TestParallelism>20</TestParallelism>
    <MSVSVersion>2019</MSVSVersion>
    <PulumiRoot Condition="'$(PulumiRoot)' == ''">C:\Pulumi\</PulumiRoot>
    <PulumiBin>$(PulumiRoot)\bin</PulumiBin>
  </PropertyGroup>

  <UsingTask TaskName="ReplaceFileText" TaskFactory="RoslynCodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
    <ParameterGroup>
      <InputFilename ParameterType="System.String" Required="true" />
      <OutputFilename ParameterType="System.String" Required="true" />
      <MatchExpression ParameterType="System.String" Required="true" />
      <ReplacementText ParameterType="System.String" Required="true" />
    </ParameterGroup>
    <Task>
      <Using Namespace="System" />
      <Using Namespace="System.IO" />
      <Using Namespace="System.Text.RegularExpressions" />
      <Code Type="Fragment" Language="cs">
        <![CDATA[
            File.WriteAllText(
                OutputFilename,
                Regex.Replace(File.ReadAllText(InputFilename), MatchExpression, ReplacementText)
                );
          ]]>
      </Code>
    </Task>
  </UsingTask>

  <!-- Conventions
  Each of the SDKs have their own section in this file and follow the format:
  * BuildLanguageSdk

  The BuildLangaugeSDK then dependes on a number of subtargets that differ based on the langage we are building. They follow
  the structure:
  * LanguageDependencies
  * LanguageBuild          (Required)
  * LanguageInstallPackage (Required)
  * LanguageInstallPlugin

  There may be an additional step for copying packages around.
  -->

  <!-- This section is where we build and package the DotNet SDK -->
  <Target Name="BuildDotNetSDK"
           DependsOnTargets="DotNetBuild;DotNetInstallPlugin;CopyNugetPackages">
  </Target>

  <Target Name="DotNetBuild">
    <Exec Command="pulumictl get version --language dotnet" ConsoleToMSBuild="true">
        <Output TaskParameter="ConsoleOutput" PropertyName="Version" />
    </Exec>
    <PropertyGroup>
      <VersionPart>$(Version.Split("-")[0])</VersionPart>
      <VersionPrefix>$(VersionPart.Replace("v",""))</VersionPrefix>
    </PropertyGroup>
    <Exec Command="dotnet build dotnet.sln /p:Version=$(Version)"
          WorkingDirectory="$(DotNetSdkDirectory)" />
    <Exec Command="go install -ldflags &quot;-X github.com/pulumi/pulumi/sdk/v3/go/common/version.Version=$(Version)&quot; github.com/pulumi/pulumi/sdk/v3/dotnet/cmd/pulumi-language-dotnet"
          WorkingDirectory="$(SdkDirectory)"/>

  </Target>

  <Target Name="DotNetInstallPlugin">
    <Exec Command="pulumictl get version --language dotnet" ConsoleToMSBuild="true">
      <Output TaskParameter="ConsoleOutput" PropertyName="Version" />
    </Exec>
    <Exec Command="go install -ldflags &quot;-X github.com/pulumi/pulumi/sdk/v3/go/common/version.Version=$(Version)&quot; github.com/pulumi/pulumi/sdk/v3/dotnet/cmd/pulumi-language-dotnet"
      EnvironmentVariables="GOBIN=$(PulumiBin)"
      WorkingDirectory="$(SdkDirectory)"/>

  </Target>

  <Target Name="CopyNugetPackages">
    <ItemGroup>
      <DotNetNupkgFile Include="$(DotNetSdkDirectory)\**\*.nupkg" />
    </ItemGroup>

    <Copy SourceFiles="@(DotNetNupkgFile)"
          DestinationFolder="$(PulumiRoot)\nuget" />
  </Target>

  <!-- This is where we build and install the Go SDK -->
  <Target Name="BuildGoSDK"
          DependsOnTargets="GoBuild;GoInstallPlugin">
  </Target>

  <Target Name="GoBuild">
    <Exec Command="pulumictl get version" ConsoleToMSBuild="true">
      <Output TaskParameter="ConsoleOutput" PropertyName="Version" />
    </Exec>
    <Exec Command="go install -ldflags &quot;-X github.com/pulumi/pulumi/sdk/v3/go/common/version.Version=$(Version)&quot; github.com/pulumi/pulumi/sdk/v3/go/pulumi-language-go"
        WorkingDirectory="$(SdkDirectory)"/>

  </Target>

  <Target Name="GoInstallPlugin">
    <Exec Command="pulumictl get version" ConsoleToMSBuild="true">
      <Output TaskParameter="ConsoleOutput" PropertyName="Version" />
    </Exec>
    <Exec Command="go install -ldflags &quot;-X github.com/pulumi/pulumi/sdk/v3/go/common/version.Version=$(Version)&quot; github.com/pulumi/pulumi/sdk/v3/go/pulumi-language-go"
          EnvironmentVariables="GOBIN=$(PulumiBin)"
          WorkingDirectory="$(SdkDirectory)"/>

  </Target>

  <!-- This is where we build and install the NodeJS SDK -->
  <Target Name="BuildNodeJSSDK"
          DependsOnTargets="NodeJSDependencies;NodeJSBuild;NodeJSInstallPlugin;CopyNodeJSPackages">
  </Target>

  <Target Name="NodeJSDependencies">
    <Exec Command="yarn install"
          WorkingDirectory="$(NodeJSSdkDirectory)" />
  </Target>

  <Target Name="NodeJSBuild">
    <Exec Command="pulumictl get version --language javascript" ConsoleToMSBuild="true">
      <Output TaskParameter="ConsoleOutput" PropertyName="Version" />
    </Exec>
    <Exec Command="yarn run tsc" WorkingDirectory="$(NodeJSSdkDirectory)" />
    <Copy SourceFiles="$(NodeJSSdkDirectory)\package.json" DestinationFiles="$(NodeJSSdkDirectory)\bin\package.json" />
    <Exec Command="node &quot;$(RepoRootDirectory)\scripts\reversion.js&quot; &quot;$(NodeJSSdkDirectory)\bin\package.json&quot; $(Version)" />
    <Exec Command="node &quot;$(RepoRootDirectory)\scripts\reversion.js&quot; &quot;$(NodeJSSdkDirectory)\bin\version.js&quot; $(Version)" />
    <!-- Copy Protos -->
    <ItemGroup>
      <NodeSdkProtos Include="$(NodeJSSdkDirectory)\proto\*.js" />
    </ItemGroup>
    <Copy SourceFiles="@(NodeSdkProtos)"
          DestinationFolder="$(NodeJSSdkDirectory)\bin\proto" />
    <!-- Copy Language Cases -->
    <ItemGroup>
      <NodeSdkTestDataFiles Include="$(NodeJSSdkDirectory)\tests\runtime\langhost\cases\**\*" />
    </ItemGroup>
    <Copy SourceFiles="@(NodeSdkTestDataFiles)"
          DestinationFolder="$(NodeJSSdkDirectory)\bin\tests\runtime\langhost\cases" />
    <Exec Command="go install -ldflags &quot;-X github.com/pulumi/pulumi/sdk/v3/go/common/version.Version=$(Version)&quot; github.com/pulumi/pulumi/sdk/v3/nodejs/cmd/pulumi-language-nodejs"
          WorkingDirectory="$(SdkDirectory)"/>

  </Target>

  <Target Name="NodeJSInstallPlugin">
    <ItemGroup>
      <NodeJSDistFiles Include="$(NodeJSSdkDirectory)\dist\*.cmd" />
    </ItemGroup>
    <Copy SourceFiles="@(NodeJSDistFiles)"
          DestinationFolder="$(PulumiBin)\" />
    <Exec Command="pulumictl get version --language javascript" ConsoleToMSBuild="true">
      <Output TaskParameter="ConsoleOutput" PropertyName="Version" />
    </Exec>
    <Exec Command="go install -ldflags &quot;-X github.com/pulumi/pulumi/sdk/v3/go/common/version.Version=$(Version)&quot; github.com/pulumi/pulumi/sdk/v3/nodejs/cmd/pulumi-language-nodejs"
          EnvironmentVariables="GOBIN=$(PulumiBin)"
          WorkingDirectory="$(SdkDirectory)"/>

  </Target>

  <Target Name="CopyNodeJSPackages">
    <MakeDir Directories="$(PulumiRoot)\node_modules\@pulumi\pulumi"/>
    <ItemGroup>
      <BinFiles Include="$(NodeJSSdkDirectory)\bin\**\*.*" />
    </ItemGroup>
    <Copy
          SourceFiles="@(BinFiles)"
          DestinationFiles="@(BinFiles->'$(PulumiRoot)\node_modules\@pulumi\pulumi\%(RecursiveDir)%(Filename)%(Extension)')" />
    <ItemGroup>
      <YarnFile Include="$(NodeJSSdkDirectory)\yarn.lock" />
    </ItemGroup>
    <Copy SourceFiles="@(YarnFile)"
          DestinationFolder="$(PulumiRoot)\node_modules\@pulumi\pulumi" />
    <RemoveDir Directories="$(PulumiRoot)\node_modules\@pulumi\pulumi\node_modules" />
    <Exec Command="yarn install --prefer-offline --production &amp;&amp; (yarn unlink > NUL || true) &amp;&amp; yarn link"
          WorkingDirectory="$(PulumiRoot)\node_modules\@pulumi\pulumi" />
  </Target>

  <!-- This is where we build and install the Python SDK -->
  <Target Name="BuildPythonSDK"
          DependsOnTargets="PythonDependencies;PythonBuild;PythonInstallPlugin">
  </Target>

  <Target Name="PythonDependencies">
    <MakeDir Directories="$(PythonSdkDirectory)\env\src"/>
    <Exec Command="pipenv install --dev"
          WorkingDirectory="$(PythonSdkDirectory)\env\src" />
  </Target>

  <Target Name="PythonBuild">
    <Exec Command="pulumictl get version --language python" ConsoleToMSBuild="true">
      <Output TaskParameter="ConsoleOutput" PropertyName="PypiVersion" />
    </Exec>
    <Exec Command="pulumictl get version" ConsoleToMSBuild="true">
      <Output TaskParameter="ConsoleOutput" PropertyName="Version" />
    </Exec>
    <ItemGroup>
      <PythonLibFiles Include="$(PythonSdkDirectory)\lib\**\*.*" />
    </ItemGroup>
    <Copy
          SourceFiles="@(PythonLibFiles)"
          DestinationFiles="@(PythonLibFiles->'$(PythonSdkDirectory)\env\src\%(RecursiveDir)%(Filename)%(Extension)')" />
    <ReplaceFileText
            InputFilename="$(PythonSdkDirectory)\env\src\setup.py"
            OutputFilename="$(PythonSdkDirectory)\env\src\setup.py"
            MatchExpression="\$\{VERSION\}"
            ReplacementText="$(PypiVersion)" />
    <ItemGroup>
      <ReadMeFile Include="$(RepoRootDirectory)\README.md" />
    </ItemGroup>
    <Copy SourceFiles="@(ReadMeFile)"
          DestinationFolder="$(PythonSdkDirectory)\env\src" />
    <Exec Command="pipenv run python setup.py build bdist_wheel --universal"
          WorkingDirectory="$(PythonSdkDirectory)\env\src" />
    <Exec Command="go install -ldflags &quot;-X github.com/pulumi/pulumi/sdk/v3/go/common/version.Version=$(Version)&quot; github.com/pulumi/pulumi/sdk/v3/python/cmd/pulumi-language-python"
    WorkingDirectory="$(SdkDirectory)"/>

  </Target>

  <Target Name="PythonInstallPlugin">
    <ItemGroup>
      <PythonLanguageExecFiles Include="$(PythonSdkDirectory)\cmd\pulumi-language-python-exec" />
    </ItemGroup>
    <Copy SourceFiles="@(PythonLanguageExecFiles)"
          DestinationFolder="$(PulumiBin)\" />
    <ItemGroup>
      <PythonDistFiles Include="$(PythonSdkDirectory)\dist\pulumi-resource-pulumi-python.cmd" />
    </ItemGroup>
    <Copy SourceFiles="@(PythonDistFiles)"
          DestinationFolder="$(PulumiBin)\" />
    <Exec Command="pulumictl get version" ConsoleToMSBuild="true">
      <Output TaskParameter="ConsoleOutput" PropertyName="Version" />
    </Exec>
    <Exec Command="go install -ldflags &quot;-X github.com/pulumi/pulumi/sdk/v3/go/common/version.Version=$(Version)&quot; github.com/pulumi/pulumi/sdk/v3/python/cmd/pulumi-language-python"
          EnvironmentVariables="GOBIN=$(PulumiBin)"
          WorkingDirectory="$(SdkDirectory)"/>

  </Target>

  <!-- Install the Pulumi SDK -->
  <Target Name="InstallPulumiPlugin">
    <Exec Command="pulumictl get version" ConsoleToMSBuild="true">
      <Output TaskParameter="ConsoleOutput" PropertyName="Version" />
    </Exec>
    <Exec Command="go install -ldflags &quot;-X github.com/pulumi/pulumi/pkg/v3/version.Version=v$(Version)&quot; github.com/pulumi/pulumi/pkg/v3/cmd/pulumi"
       EnvironmentVariables="GOBIN=$(PulumiBin)"
       WorkingDirectory="$(PkgDirectory)"/>

  </Target>

  <!-- Build -->
  <Target Name="Build"
          DependsOnTargets="BuildDotNetSDK;BuildGoSDK;BuildNodeJSSDK;BuildPythonSDK;InstallPulumiPlugin">
  </Target>

  <!-- This is where we build and install the NodeJS SDK -->
  <Target Name="BuildTests"
          DependsOnTargets="TestDependencies;TestBuild">
  </Target>

  <Target Name="TestDependencies">
    <Exec Command="yarn install"
      WorkingDirectory="$(TestsDirectory)\integration\construct_component\testcomponent" />
    <Exec Command="yarn link @pulumi/pulumi"
      WorkingDirectory="$(TestsDirectory)\integration\construct_component\testcomponent" />
    <Exec Command="yarn install"
      WorkingDirectory="$(TestsDirectory)\integration\construct_component_slow\testcomponent" />
    <Exec Command="yarn link @pulumi/pulumi"
      WorkingDirectory="$(TestsDirectory)\integration\construct_component_slow\testcomponent" />
    <Exec Command="yarn install"
      WorkingDirectory="$(TestsDirectory)\integration\construct_component_plain\testcomponent" />
    <Exec Command="yarn link @pulumi/pulumi"
      WorkingDirectory="$(TestsDirectory)\integration\construct_component_plain\testcomponent" />
    <Exec Command="yarn install"
      WorkingDirectory="$(TestsDirectory)\integration\component_provider_schema\testcomponent" />
    <Exec Command="yarn link @pulumi/pulumi"
      WorkingDirectory="$(TestsDirectory)\integration\component_provider_schema\testcomponent" />
    <Exec Command="yarn install"
      WorkingDirectory="$(TestsDirectory)\integration\construct_component_unknown\testcomponent" />
    <Exec Command="yarn link @pulumi/pulumi"
      WorkingDirectory="$(TestsDirectory)\integration\construct_component_unknown\testcomponent" />
  </Target>

  <Target Name="TestBuild">
    <Exec Command="go build -o pulumi-resource-testprovider.exe" WorkingDirectory="$(TestsDirectory)\testprovider" />
    <Exec Command="yarn run tsc" WorkingDirectory="$(TestsDirectory)\integration\construct_component\testcomponent" />
    <Exec Command="go build -o pulumi-resource-testcomponent.exe" WorkingDirectory="$(TestsDirectory)\integration\construct_component\testcomponent-go" />
    <Exec Command="yarn run tsc" WorkingDirectory="$(TestsDirectory)\integration\construct_component_slow\testcomponent" />
    <Exec Command="yarn run tsc" WorkingDirectory="$(TestsDirectory)\integration\construct_component_plain\testcomponent" />
    <Exec Command="go build -o pulumi-resource-testcomponent.exe" WorkingDirectory="$(TestsDirectory)\integration\construct_component_plain\testcomponent-go" />
    <Exec Command="yarn run tsc" WorkingDirectory="$(TestsDirectory)\integration\component_provider_schema\testcomponent" />
    <Exec Command="go build -o pulumi-resource-testcomponent.exe" WorkingDirectory="$(TestsDirectory)\integration\component_provider_schema\testcomponent-go" />
    <Exec Command="yarn run tsc" WorkingDirectory="$(TestsDirectory)\integration\construct_component_unknown\testcomponent" />
    <Exec Command="go build -o pulumi-resource-testcomponent.exe" WorkingDirectory="$(TestsDirectory)\integration\construct_component_unknown\testcomponent-go" />

    <!-- Install pulumi SDK into the venv managed by pipenv. -->
    <Exec Command="pipenv run pip install -e ."
          WorkingDirectory="$(PythonSdkDirectory)\env\src" />
  </Target>

  <!-- Tests -->
  <Target Name="Tests"
	  DependsOnTargets="BuildTests">

    <Exec Command="go test -timeout 5m -parallel $(TestParallelism) .\backend\..."
          IgnoreExitCode="true"
          WorkingDirectory="$(PkgDirectory)">
      <Output TaskParameter="ExitCode" PropertyName="BackendTestsExitCode" />
    </Exec>

    <Exec Command="pipenv run pytest -ra lib\test\automation"
          WorkingDirectory="$(PythonSdkDirectory)" />

    <Error Text="backend tests (.\pkg\backend) failed"
           Condition="$(BackendTestsExitCode) != 0"/>

    <Exec Command="go test -timeout 1h -cover -parallel $(TestParallelism) .\examples"
          IgnoreExitCode="true"
          WorkingDirectory="$(TestsDirectory)">
      <Output TaskParameter="ExitCode" PropertyName="ExamplesTestExitCode" />
    </Exec>

    <Error Text="examples tests (.\tests\examples) failed"
           Condition="$(ExamplesTestExitCode) != 0"/>

    <Exec Command="go test -timeout 1h -cover -parallel $(TestParallelism) -tags=all .\integration"
          IgnoreExitCode="true"
          WorkingDirectory="$(TestsDirectory)">
      <Output TaskParameter="ExitCode" PropertyName="IntegrationTestExitCode" />
    </Exec>

    <Error Text="integration tests (.\tests\integration) failed"
           Condition="$(IntegrationTestExitCode) != 0"/>
  </Target>

  <Target Name="CIBuild"
          DependsOnTargets="Build;Tests" />
</Project>
