<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.tasks))\dir.tasks" />
  <Import Project="$(RepoRoot)/build/compile/LzmaArchive.targets" />
  <Import Project="$(RepoRoot)/build/MSBuildExtensions.targets" />

  <PropertyGroup>
    <VersionPrefix>$(CliVersionPrefix)</VersionPrefix>
    <TargetFramework>$(CliTargetFramework)</TargetFramework>
    <RuntimeFrameworkVersion>$(MicrosoftNETCoreAppPackageVersion)</RuntimeFrameworkVersion>
    <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
    <CopyBuildOutputToPublishDirectory>false</CopyBuildOutputToPublishDirectory>
    <AssetTargetFallback>dotnet5.4</AssetTargetFallback>
    <PublishDir>$(SdkOutputDirectory)</PublishDir>
    <VersionSuffix>$(CommitCount)</VersionSuffix>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.NETCore.App" Version="$(MicrosoftNETCoreAppPackageVersion)" />
    <PackageReference Include="NuGet.Build.Tasks" Version="$(NuGetBuildTasksPackageVersion)" />
    <PackageReference Include="Microsoft.Build.NuGetSdkResolver" Version="$(MicrosoftBuildNuGetSdkResolverPackageVersion)" />
    <PackageReference Include="Microsoft.TestPlatform.CLI" Version="$(MicrosoftTestPlatformCLIPackageVersion)" />
    <PackageReference Include="Microsoft.TestPlatform.Build" Version="$(MicrosoftTestPlatformBuildPackageVersion)" />
    <PackageReference Condition=" '$(DotNetBuildFromSource)' != 'true' " Include="NuGet.Localization" Version="$(NuGetProjectModelPackageVersion)" />
    <PackageReference Include="NuGet.ProjectModel" Version="$(NuGetProjectModelPackageVersion)" />
    <PackageReference Include="Microsoft.NETCore.Compilers" Version="$(MicrosoftNETCoreCompilersPackageVersion)">
      <ExcludeAssets>All</ExcludeAssets>
    </PackageReference>
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\dotnet\dotnet.csproj" />
    <ProjectReference Include="..\tool_msbuild\tool_msbuild.csproj" />
    <ProjectReference Include="..\tool_nuget\tool_nuget.csproj" />
  </ItemGroup>

  <ItemGroup>
    <Content Include="minimumMSBuildVersion">
      <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
    </Content>
  </ItemGroup>

  <Target Name="PublishAspNetSharedFramework"
          AfterTargets="CrossgenPublishDir">
    <ItemGroup>
      <AspNetSharedFramework Remove="*" />
      <AspNetSharedFramework Include="$(AspNetCoreSharedFxPublishDirectory)/**/*" />
    </ItemGroup>

    <Copy SourceFiles="@(AspNetSharedFramework)"
          DestinationFiles="@(AspNetSharedFramework->'$(OutputDirectory)/%(RecursiveDir)%(Filename)%(Extension)')" />
  </Target>

  <Target Name="PublishSharedFramework"
          BeforeTargets="Publish">
    <ItemGroup>
      <SharedFramework Remove="*" />
      <SharedFramework Include="$(SharedFrameworkPublishDirectory)/**/*" />
    </ItemGroup>

    <Copy SourceFiles="@(SharedFramework)"
          DestinationFiles="@(SharedFramework->'$(OutputDirectory)/%(RecursiveDir)%(Filename)%(Extension)')" />
  </Target>

  <Target Name="PublishVersionFile"
          BeforeTargets="Publish">

    <WriteLinesToFile File="$(PublishDir)/.version"
                      Lines="$(CommitHash);$(SdkVersion);$(Rid)"
                      Overwrite="true" />
  </Target>

  <Target Name="PublishRoslyn"
          BeforeTargets="Publish">

    <ItemGroup>
      <RoslynBits Include="$(NuGetPackagesDir)/microsoft.netcore.compilers/$(MicrosoftNETCoreCompilersPackageVersion)/tools/**/*" />
    </ItemGroup>
    <Copy SourceFiles="@(RoslynBits)" DestinationFiles="@(RoslynBits->'$(RoslynDirectory)/%(RecursiveDir)%(Filename)%(Extension)')" />
    <ItemGroup>
      <RoslynFrameworkAssemblies Include="$(RoslynDirectory)/System.*.dll;$(RoslynDirectory)/runtimes/**/System.*.dll" Exclude="$(RoslynDirectory)/runtimes/**/System.IO.Pipes.AccessControl.dll"/>
    </ItemGroup>
    <Delete Files="@(RoslynFrameworkAssemblies)" />
  </Target>

  <Target Name="PublishFSharp"
          BeforeTargets="Publish">

    <DotNetPublish ToolPath="$(PreviousStageDirectory)"
                   Configuration="$(Configuration)"
                   ProjectPath="$(SrcDirectory)/tool_fsharp/tool_fsc.csproj" MSBuildArgs="/p:PublishDir=$(FSharpDirectory)" />
  </Target>

  <Target Name="GenerateCliRuntimeConfigurationFiles"
          AfterTargets="Publish">
    <RemoveAssetFromDepsPackages DepsFile="$(PublishDir)/$(TargetName).deps.json"
                                 SectionName="runtime"
                                 AssetPath="%(BundledToolProjects.Identity).dll" />

    <Copy SourceFiles="$(PublishDir)/$(TargetName).deps.json"
          DestinationFiles="$(PublishDir)/%(BundledTools.Identity).deps.json" />

    <Copy SourceFiles="$(PublishDir)/$(TargetName).runtimeconfig.json"
          DestinationFiles="$(PublishDir)/%(BundledTools.Identity).runtimeconfig.json" />

    <Delete Files="$(PublishDir)/$(TargetName).deps.json;
                   $(PublishDir)/$(TargetName).runtimeconfig.json;
                   $(PublishDir)/%(BundledToolProjects.Identity).dll;
                   $(PublishDir)/%(BundledToolProjects.Identity).pdb" />

    <ChangeEntryPointLibraryName
          DepsFile="$(PublishDir)/%(BundledTools.Identity).deps.json"
          NewName="%(BundledTools.Identity).deps.json" />
  </Target>

  <Target Name="PublishMSBuildExtensions"
          DependsOnTargets="GenerateMSBuildExtensions"
          AfterTargets="Publish"
          BeforeTargets="GenerateCliRuntimeConfigurationFiles">
    <ItemGroup>
      <MSBuildExtensionsContent Update="@(MSBuildExtensionsContent)">
        <DestinationPath Condition="'%(MSBuildExtensionsContent.DestinationPath)' == ''">$(PublishDir)/%(MSBuildExtensionsContent.DeploymentSubpath)%(RecursiveDir)%(Filename)%(Extension)</DestinationPath>
      </MSBuildExtensionsContent>
    </ItemGroup>

      <Copy SourceFiles="@(MSBuildExtensionsContent)"
            DestinationFiles="%(MSBuildExtensionsContent.DestinationPath)" />

      <PropertyGroup>
        <MSBuildTargetsDirectory>$(PublishDir)/runtimes/any/native</MSBuildTargetsDirectory>
      </PropertyGroup>

      <ItemGroup>
        <NuPkgContentForMSBuildExtensions Include="$(MSBuildTargetsDirectory)/**/*.targets;
                                                   $(MSBuildTargetsDirectory)/**/*.props;
                                                   $(MSBuildTargetsDirectory)/**/*.overridetasks;
                                                   $(MSBuildTargetsDirectory)/**/*.tasks" />

        <NuPkgContentForMSBuildExtensionsRelativePaths Include="@(NuPkgContentForMSBuildExtensions->'runtimes/any/native/%(RecursiveDir)%(Filename)%(Extension)')" />
      </ItemGroup>

      <Move SourceFiles="@(NuPkgContentForMSBuildExtensions)"
            DestinationFiles="@(NuPkgContentForMSBuildExtensions->'$(PublishDir)/%(RecursiveDir)%(Filename)%(Extension)')" />

      <RemoveAssetFromDepsPackages DepsFile="$(PublishDir)/$(TargetName).deps.json"
                                   SectionName="runtimeTargets"
                                   AssetPath="%(NuPkgContentForMSBuildExtensionsRelativePaths.Identity)" />
  </Target>

  <!-- The msdia140typelib_clr0200.dll file is not MIT licensed (and it only used on Windows). Remove it, so
       we can MIT license the published dotnet -->
  <Target Name="RemoveMSDiaTypeLib"
          AfterTargets="Publish"
          Condition="'$(OSName)' != 'win'">
    <Delete Files="$(PublishDir)/TestHost/msdia140typelib_clr0200.dll" />
  </Target>

  <Target Name="PublishSdks"
          AfterTargets="Publish">
    <ItemGroup>
      <SdksToBundle Include="$(RepoRoot)/build/RestoreDependency.proj">
        <Properties>
          CLIBuildDll=$(CLIBuildDll);
          NuGetPackagesDir=$(NuGetPackagesDir);
          SdkLayoutDirectory=$(SdkOutputDirectory)/Sdks/%(BundledSdk.Identity);
          DependencyPackageName=%(BundledSdk.Identity);
          DependencyPackageVersion=%(BundledSdk.Version);
          PreviousStageDirectory=$(PreviousStageDirectory)
        </Properties>
      </SdksToBundle>
    </ItemGroup>

    <MSBuild
      BuildInParallel="False"
      Projects="@(SdksToBundle)">
    </MSBuild>
  </Target>

  <Target Name="PublishTemplates"
          AfterTargets="Publish">
    <ItemGroup>
      <TemplatesToBundle Include="$(RepoRoot)/build/BundledTemplates.proj">
        <Properties>
          TemplateLayoutDirectory=$(SdkOutputDirectory)/Templates;
          TemplateFillInPackageName=%(BundledTemplate.Identity);
          TemplateFillInPackageVersion=%(BundledTemplate.Version);
          PreviousStageDirectory=$(PreviousStageDirectory)
        </Properties>
      </TemplatesToBundle>
    </ItemGroup>

    <MSBuild
      BuildInParallel="False"
      Projects="@(TemplatesToBundle)">
    </MSBuild>
  </Target>

  <Target Name="PublishDotnetTools"
          Condition="'$(CLIBUILD_SKIP_BUNDLEDDOTNETTOOLS)' != 'true'"
          AfterTargets="Publish">
    <ItemGroup>
      <DotnetToolsToBundle Include="$(RepoRoot)/build/BundledDotnetTools.proj">
        <Properties>
          DotnetToolsLayoutDirectory=$(SdkOutputDirectory)/DotnetTools;
          TemplateFillInPackageName=%(BundledDotnetTools.Identity);
          TemplateFillInPackageVersion=%(BundledDotnetTools.Version);
          PreviousStageDirectory=$(PreviousStageDirectory)
        </Properties>
      </DotnetToolsToBundle>
    </ItemGroup>

    <MSBuild
      BuildInParallel="False"
      Projects="@(DotnetToolsToBundle)">
    </MSBuild>
  </Target>

  <Target Name="PublishAppHostTemplate"
          AfterTargets="Publish">

    <PropertyGroup>
      <NETCoreDotNetAppHostPackageName>Microsoft.NETCore.DotNetAppHost</NETCoreDotNetAppHostPackageName>
    </PropertyGroup>

    <ItemGroup>
      <NETCoreDotNetAppHostPackageVersions Include="@(PackageDefinitions->'%(Version)')"
                                           Condition="%(PackageDefinitions.Name) == $(NETCoreDotNetAppHostPackageName)" />
    </ItemGroup>

    <Error Condition="@(NETCoreDotNetAppHostPackageVersions->Distinct()->Count()) != 1"
           Text="Failed to determine the $(NETCoreDotNetAppHostPackageName) version pulled in Microsoft.NETCore.App" />

    <PropertyGroup>
      <_NETCoreDotNetAppHostPackageVersion>@(NETCoreDotNetAppHostPackageVersions->Distinct())</_NETCoreDotNetAppHostPackageVersion>
    </PropertyGroup>

    <ItemGroup>
      <AppHostTemplate Include="$(RepoRoot)/build/AppHostTemplate.proj">
        <Properties>
          AppHostTemplatePath=$(SdkOutputDirectory)/AppHostTemplate;
          TemplateFillInPackageName=$(NETCoreDotNetAppHostPackageName);
          TemplateFillInPackageVersion=$(_NETCoreDotNetAppHostPackageVersion);
          PreviousStageDirectory=$(PreviousStageDirectory);
          AppHostIntermediateDirectory=$(IntermediateDirectory)/AppHostIntermediate
        </Properties>
      </AppHostTemplate>
    </ItemGroup>

    <MSBuild
      BuildInParallel="False"
      Projects="@(AppHostTemplate)">
    </MSBuild>

  </Target>

  <Target Name="PublishLzmaArchive"
          Condition="'$(CLIBUILD_SKIP_LZMA)' != 'true'"
          DependsOnTargets="GetNuGetPackagesArchive"
          AfterTargets="Publish">
  </Target>

  <Target Name="CrossgenPublishDir"
          Condition=" '$(DISABLE_CROSSGEN)' == '' And '$(Architecture)' != 'arm' "
          AfterTargets="PublishSdks">
    <ItemGroup>
      <RoslynFiles Include="$(PublishDir)Roslyn\bincore\**\*" />
      <FSharpFiles Include="$(PublishDir)FSharp\**\*" Exclude="$(PublishDir)FSharp\FSharp.Build.dll" />
      <RemainingFiles Include="$(PublishDir)**\*" Exclude="@(RoslynFiles);@(FSharpFiles)" />

      <!-- Removing Full CLR built TestHost assemblies from getting Crossgen as it is throwing error -->
      <RemainingFiles Remove="$(PublishDir)TestHost*\**\*" />
      <RemainingFiles Remove="$(PublishDir)Sdks\**\*" />
      <RemainingFiles Remove="$(PublishDir)**\Microsoft.TestPlatform.Extensions.EventLogCollector.dll" />

      <!-- Add back the .NET Core assemblies in the Sdks folder -->
      <RemainingFiles Include="$(PublishDir)Sdks\Microsoft.NET.Sdk\tools\netcoreapp2.0\**\*" />
      <RemainingFiles Include="$(PublishDir)Sdks\NuGet.Build.Tasks.Pack\CoreCLR\**\*" />

      <!-- Don't try to CrossGen .NET Framework support assemblies for .NET Standard -->
      <RemainingFiles Remove="$(PublishDir)Microsoft\Microsoft.NET.Build.Extensions\net*\**\*" />

      <!-- Don't crossgen satellite assemblies -->
      <RoslynFiles Remove="$(PublishDir)Roslyn\bincore\**\*.resources.dll" />
      <FSharpFiles Remove="$(PublishDir)FSharp\**\*.resources.dll" />
      <RemainingFiles Remove="$(PublishDir)**\*.resources.dll" />

      <DiasymReaderPath Include="$(SharedFrameworkNameVersionPath)/Microsoft.DiaSymReader.Native.*.dll" />

      <!-- MSBuild includes reference assemblies to compile in-memory tasks. Don't try to crossgen. -->
      <RemainingFiles Remove="$(PublishDir)ref\*.dll" />
    </ItemGroup>

    <AddMetadataIsPE Items="@(RoslynFiles)">
      <Output TaskParameter="ResultItems" ItemName="RoslynFilesWithPEMarker" />
    </AddMetadataIsPE>
    <AddMetadataIsPE Items="@(FSharpFiles)">
      <Output TaskParameter="ResultItems" ItemName="FSharpFilesWithPEMarker" />
    </AddMetadataIsPE>
    <AddMetadataIsPE Items="@(RemainingFiles)">
      <Output TaskParameter="ResultItems" ItemName="RemainingFilesWithPEMarker" />
    </AddMetadataIsPE>

    <ItemGroup>
      <RoslynTargets Include="%(RoslynFilesWithPEMarker.FullPath)" Condition=" '%(RoslynFilesWithPEMarker.IsPE)' == 'True' " />
      <FSharpTargets Include="%(FSharpFilesWithPEMarker.FullPath)" Condition=" '%(FSharpFilesWithPEMarker.IsPE)' == 'True' " />
      <RemainingTargets Include="%(RemainingFilesWithPEMarker.FullPath)" Condition=" '%(RemainingFilesWithPEMarker.IsPE)' == 'True' " />

      <RoslynFolders Include="@(RoslynTargets-&gt;DirectoryName()-&gt;Distinct())" />
      <FSharpFolders Include="@(FSharpTargets-&gt;DirectoryName()-&gt;Distinct())" />
      <RemainingFolders Include="@(RemainingTargets-&gt;DirectoryName()-&gt;Distinct())" />

      <!-- FSharp.Build.dll causes the FSharp folder to be included. Remove it, as we don't want other FSharp dlls being included in the crossgen. -->
      <RemainingFolders Remove="$(PublishDir)FSharp\**\*" />
    </ItemGroup>

    <!-- Ensure crossgen tool is executable.  See https://github.com/NuGet/Home/issues/4424 -->
    <Chmod Condition=" '$(OSName)' != 'win' "
           Glob="$(CrossgenPath)"
           Mode="u+x" />

    <!-- Crossgen does not support generating symbols on Mac  -->
    <PropertyGroup Condition="'$(CreateCrossgenSymbols)' == ''">
      <CreateCrossgenSymbols>true</CreateCrossgenSymbols>
      <CreateCrossgenSymbols Condition="'$(OSName)' == 'osx'">false</CreateCrossgenSymbols>
   </PropertyGroup>

    <Crossgen
        SourceAssembly="%(RoslynTargets.FullPath)"
        DestinationPath="%(RoslynTargets.FullPath)"
        JITPath="$(LibCLRJitPath)"
        CrossgenPath="$(CrossgenPath)"
        ReadyToRun="True"
        CreateSymbols="$(CreateCrossgenSymbols)"
        DiasymReaderPath="@(DiasymReaderPath)"
        PlatformAssemblyPaths="@(PlatformAssemblies);@(RoslynFolders);$(SharedFrameworkNameVersionPath)" />

    <Crossgen
        SourceAssembly="%(FSharpTargets.FullPath)"
        DestinationPath="%(FSharpTargets.FullPath)"
        JITPath="$(LibCLRJitPath)"
        CrossgenPath="$(CrossgenPath)"
        ReadyToRun="True"
        CreateSymbols="$(CreateCrossgenSymbols)"
        DiasymReaderPath="@(DiasymReaderPath)"
        PlatformAssemblyPaths="@(PlatformAssemblies);@(FSharpFolders);$(SharedFrameworkNameVersionPath)" />

    <Crossgen
        SourceAssembly="%(RemainingTargets.FullPath)"
        DestinationPath="%(RemainingTargets.FullPath)"
        JITPath="$(LibCLRJitPath)"
        CrossgenPath="$(CrossgenPath)"
        ReadyToRun="True"
        CreateSymbols="$(CreateCrossgenSymbols)"
        DiasymReaderPath="@(DiasymReaderPath)"
        PlatformAssemblyPaths="@(PlatformAssemblies);@(RemainingFolders);$(SharedFrameworkNameVersionPath)" />
  </Target>

  <Target Name="ChmodPublishDir"
          AfterTargets="CrossgenPublishDir"
          Condition=" '$(OSName)' != 'win' ">

    <Exec Command="find $(SdkOutputDirectory) -type d -exec chmod 755 {} \;" />
    <Exec Command="find $(SdkOutputDirectory) -type f -exec chmod 644 {} \;" />
    <Chmod Mode="755" Glob="$(SdkOutputDirectory)/FSharp/RunFsc.sh" />
  </Target>

  <Target Name="SeparateSymbolsFromPublishDir"
          AfterTargets="CrossgenPublishDir">
    <ItemGroup>
      <PdbsToMove Include="$(PublishDir)/**/*.pdb" />
      <PdbsToMove Include="$(PublishDir)/**/*.ni.*.map" />
    </ItemGroup>

    <Move SourceFiles="@(PdbsToMove)"
          DestinationFiles="@(PdbsToMove->'$(SymbolsDirectory)/sdk/$(SdkVersion)/%(RecursiveDir)%(Filename)%(Extension)')" />
  </Target>

  <Target Name="PublishStage2WithBackwardsCompatibleRuntimes"
          AfterTargets="PublishLzmaArchive;">
    <ItemGroup>
      <BackwardsCompatibleSharedFrameworks Remove="*" />
      <BackwardsCompatibleSharedFrameworks Include="$(BackwardsCompatibleSharedFrameworksPublishDirectory)/**/*" />

      <Stage2Cli Remove="*" />
      <Stage2Cli Include="$(OutputDirectory)/**/*" />
    </ItemGroup>

    <Copy SourceFiles="@(BackwardsCompatibleSharedFrameworks)"
          DestinationFiles="@(BackwardsCompatibleSharedFrameworks->'$(Stage2WithBackwardsCompatibleRuntimesOutputDirectory)/%(RecursiveDir)%(Filename)%(Extension)')" />

    <Copy SourceFiles="@(Stage2Cli)"
          DestinationFiles="@(Stage2Cli->'$(Stage2WithBackwardsCompatibleRuntimesOutputDirectory)/%(RecursiveDir)%(Filename)%(Extension)')" />
  </Target>

  <Target Name="RetargetVSTestConsole"
          BeforeTargets="PublishStage2WithBackwardsCompatibleRuntimes"
          AfterTargets="Publish">
    <PropertyGroup>
      <VSTestRuntimeConfigPath>$(PublishDir)/vstest.console.runtimeconfig.json</VSTestRuntimeConfigPath>
      <ReplacementPattern>"version": ".*"</ReplacementPattern>
      <ReplacementString>"version": "$(MicrosoftNETCoreAppPackageVersion)"</ReplacementString>
    </PropertyGroup>
    <ReplaceFileContents
      InputFiles="$(VSTestRuntimeConfigPath)"
      DestinationFiles="$(VSTestRuntimeConfigPath)"
      ReplacementPatterns="$(ReplacementPattern)"
      ReplacementStrings="$(ReplacementString)" />
  </Target>
</Project>
