<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Condition="Exists('..\dir.props') And '$(RepoLocalBuild)'!='true'" Project="..\dir.props" />

  <!--
    $(OS) is set to Unix/Windows_NT. This comes from an environment variable on Windows and MSBuild on Unix.
  -->
  <PropertyGroup>
    <OsEnvironment Condition="'$(OsEnvironment)'==''">$(OS)</OsEnvironment>
  </PropertyGroup>

  <!-- Initialize the basic BuildOS, BuildType, BuildConfig from build script, if present -->
  <PropertyGroup>
    <OSGroup Condition="'$(OSGroup)'==''">$(__BuildOS)</OSGroup>
    <Platform Condition="'$(Platform)'==''">$(__BuildArch)</Platform>
    <Configuration Condition="'$(Configuration)'==''">$(__BuildType)</Configuration>
  </PropertyGroup>

  <!-- 
  Projects that have no OS-specific implementations just use Debug and Release for $(Configuration).
  Projects that do have OS-specific implementations use OS_Debug and OS_Release, for all OS's we support even
  if the code is the same between some OS's (so if you have some project that just calls POSIX APIs, we still have
  OSX_[Debug|Release] and Linux_[Debug|Release] configurations.  We do this so that we place all the output under
  a single binary folder and can have a similar experience between the command line and Visual Studio.
  
  Since now have multiple *Debug and *Release configurations, ConfigurationGroup is set to Debug for any of the
  debug configurations, and to Release for any of the release configurations.
  -->

  <!-- Set default Configuration and Platform -->
  <PropertyGroup>
    <Platform Condition="'$(Platform)'==''">AnyCPU</Platform>

    <Configuration Condition="'$(Configuration)'==''">Debug</Configuration>
    <ConfigurationGroup Condition="$(Configuration.EndsWith('Debug'))">Debug</ConfigurationGroup>
    <ConfigurationGroup Condition="$(Configuration.EndsWith('Release'))">Release</ConfigurationGroup>
    <ConfigurationGroup Condition="'$(ConfigurationGroup)'==''">$(Configuration)</ConfigurationGroup>

    <OSGroup Condition="'$(OSGroup)'=='' and $(Configuration.StartsWith('Windows'))">Windows_NT</OSGroup>
    <OSGroup Condition="'$(OSGroup)'=='' and $(Configuration.StartsWith('Linux'))">Linux</OSGroup>
    <OSGroup Condition="'$(OSGroup)'=='' and $(Configuration.StartsWith('OSX'))">OSX</OSGroup>
    <OSGroup Condition="'$(OSGroup)'=='' and $(Configuration.StartsWith('FreeBSD'))">FreeBSD</OSGroup>
    <OSGroup Condition="'$(OSGroup)'==''">Windows_NT</OSGroup>
  </PropertyGroup>

  <!-- Initialize the binplace-specific BuildOS, BuildType, BuildConfig from what we have computed by now -->
  <PropertyGroup>
    <BinDirOSGroup Condition="'$(BinDirOSGroup)'==''">$(OSGroup)</BinDirOSGroup>
    <BinDirConfiguration Condition="'$(BinDirConfiguration)'==''">$(ConfigurationGroup)</BinDirConfiguration>
    <BinDirPlatform Condition="'$(BinDirPlatform)'==''">$(Platform)</BinDirPlatform>
    <BinDirPlatform Condition="'$(BinDirPlatform)'=='AnyCPU' or '$(BinDirPlatform)'=='amd64'">x64</BinDirPlatform> 
  </PropertyGroup>

  <!-- Common repo directories -->
  <PropertyGroup>
    <ProjectDir>$(MSBuildThisFileDirectory)</ProjectDir>
    <SourceDir>$(ProjectDir)src/</SourceDir>

    <!-- Output directories -->
    <BinDir Condition="'$(BinDir)'==''">$(ProjectDir)bin/</BinDir>
    <ObjDir Condition="'$(ObjDir)'==''">$(BinDir)obj/</ObjDir>
    <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'==''">$(ObjDir)</BaseIntermediateOutputPath>
    <PackageOutputRoot Condition="'$(PackageOutputRoot)'=='' and '$(NonShippingPackage)' == 'true'">$(BinDir)packages_noship/</PackageOutputRoot>
    <PackageOutputRoot Condition="'$(PackageOutputRoot)'==''">$(BinDir)packages/</PackageOutputRoot>

    <!-- Input Directories -->
    <PackagesDir Condition="'$(PackagesDir)'==''">$(ProjectDir)packages/</PackagesDir>
    <RestorePackagesPath>$(PackagesDir)</RestorePackagesPath>
    
    <ToolsDir Condition="'$(ToolsDir)'==''">$(ProjectDir)Tools/</ToolsDir>
  </PropertyGroup>

  <!-- Import Build tools common props file where repo-independent properties are found -->
  <Import Project="$(ToolsDir)Build.Common.props" Condition="Exists('$(ToolsDir)Build.Common.props')" />

  <!-- Provides package dependency version properties and verification/auto-upgrade configuration -->
  <Import Project="$(MSBuildThisFileDirectory)dependencies.props" />

  <PropertyGroup>
    <!-- Default any assembly not specifying a key to use the Open Key -->
    <AssemblyKey>Open</AssemblyKey>
  </PropertyGroup>

  <!-- Import the packaging props -->
  <Import Project="$(MSBuildThisFileDirectory)Packaging.props" />

  <!-- Set up Default symbol and optimization for Configuration -->
  <PropertyGroup Condition="'$(ConfigurationGroup)' == 'Debug'">
    <DebugSymbols Condition="'$(DebugSymbols)' == ''">true</DebugSymbols>
    <Optimize Condition="'$(Optimize)' == ''">false</Optimize>
    <DebugType Condition="'$(DebugType)' == ''">full</DebugType>
    <DefineConstants>DEBUG;TRACE;$(DefineConstants)</DefineConstants>
  </PropertyGroup>
  <PropertyGroup Condition="'$(ConfigurationGroup)' == 'Release'">
    <DebugSymbols Condition="'$(DebugSymbols)' == ''">true</DebugSymbols>
    <Optimize Condition="'$(Optimize)' == ''">true</Optimize>
    <DebugType Condition="'$(DebugType)' == ''">pdbonly</DebugType>
    <DefineConstants>TRACE;$(DefineConstants)</DefineConstants>
  </PropertyGroup>

  <!-- Disable some standard properties for building our projects -->
  <PropertyGroup>
    <NoStdLib>true</NoStdLib>
    <NoExplicitReferenceToStdLib>true</NoExplicitReferenceToStdLib>
    <AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>
    <GenerateTargetFrameworkAttribute>false</GenerateTargetFrameworkAttribute>
    <LangVersion>latest</LangVersion>
    <DebugType Condition="'$(IsProjectNLibrary)' != 'true'">portable</DebugType>
  </PropertyGroup>

  <!-- Set up handling of build warnings -->
  <PropertyGroup>
    <WarningLevel>4</WarningLevel>
    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
  </PropertyGroup>

  <!-- Set up some common paths -->
  <PropertyGroup>
    <CommonPath>$(SourceDir)Common\src</CommonPath>
    <CommonTestPath>$(SourceDir)Common\tests</CommonTestPath>
  </PropertyGroup>

  <!-- Set up the default output and intermediate paths -->
  <PropertyGroup>
    <OSPlatformConfig>$(BinDirOSGroup).$(BinDirPlatform).$(BinDirConfiguration)</OSPlatformConfig>

    <BaseOutputPath Condition="'$(BaseOutputPath)'==''">$(BinDir)</BaseOutputPath>

    <OutputPath Condition="'$(OutputPath)'==''">$(BaseOutputPath)$(OSPlatformConfig)/$(MSBuildProjectName)</OutputPath>

    <IntermediateOutputRootPath Condition="'$(IntermediateOutputRootPath)' == ''">$(BaseIntermediateOutputPath)$(OSPlatformConfig)/</IntermediateOutputRootPath>
    <IntermediateOutputPath Condition="'$(IntermediateOutputPath)' == ''">$(IntermediateOutputRootPath)$(MSBuildProjectName)</IntermediateOutputPath>

    <RuntimePath Condition="'$(RuntimePath)' == ''">$(IntermediateOutputRootPath)test-runtime/</RuntimePath>

    <!-- Use the shared tools host and runtime for testing -->
    <TestHostRootPath Condition="'$(TestHostRootPath)' == ''">$(DotnetCliPath)</TestHostRootPath>

    <PackageOutputPath Condition="'$(PackageOutputPath)'==''">$(PackageOutputRoot)$(BinDirConfiguration)/</PackageOutputPath>
    <SymbolPackageOutputPath Condition="'$(SymbolPackageOutputPath)'==''">$(PackageOutputPath)symbols/</SymbolPackageOutputPath>

    <!-- Folder where we will drop the Nuget package for the toolchain -->
    <ProductPackageDir Condition="'$(ProductPackageDir)'==''">$(BaseOutputPath)$(OSPlatformConfig)/packaging/</ProductPackageDir>

    <RestoreOutputPath Condition="'$(RestoreOutputPath)'==''">$(IntermediateOutputPath)</RestoreOutputPath>

    <AotPackageReferencePath Condition="'$(AotPackageReferencePath)'==''">$(IntermediateOutputRootPath)\AotPackageReference</AotPackageReferencePath>

    <PackagesBasePath Condition="'$(PackagesBasePath)'==''">$(BinDir)$(OSPlatformConfig)</PackagesBasePath>
  </PropertyGroup>

  <ItemGroup>
    <SupplementalTestData Include="$(RuntimePath)*" />
  </ItemGroup>

  <!-- initialize all the targets variables to false as they should only be set below -->
  <PropertyGroup>
    <TargetsWindows>false</TargetsWindows>
    <TargetsUnix>false</TargetsUnix>
    <TargetsLinux>false</TargetsLinux>
    <TargetsOSX>false</TargetsOSX>
    <TargetsFreeBSD>false</TargetsFreeBSD>
    <TargetsNetBSD>false</TargetsNetBSD>
  </PropertyGroup>

  <!-- Setup properties per OSGroup -->
  <Choose>
    <When Condition="'$(OSGroup)'=='AnyOS'">
      <PropertyGroup>
      </PropertyGroup>
    </When>
    <When Condition="'$(OSGroup)'=='Windows_NT'">
      <PropertyGroup>
        <TargetsWindows>true</TargetsWindows>
        <PackageTargetRuntime>win-corert</PackageTargetRuntime>
      </PropertyGroup>
    </When>
    <When Condition="'$(Platform)'=='wasm'">
      <PropertyGroup>
        <TargetsUnix>true</TargetsUnix>
        <TargetsWindows>false</TargetsWindows>
        <PackageTargetRuntime>unix-corert</PackageTargetRuntime>
      </PropertyGroup>
    </When>
    <When Condition="'$(OSGroup)'=='Unix'">
      <PropertyGroup>
        <TargetsUnix>true</TargetsUnix>
        <PackageTargetRuntime>unix-corert</PackageTargetRuntime>
      </PropertyGroup>
    </When>
    <When Condition="'$(OSGroup)'=='Linux'">
      <PropertyGroup>
        <TargetsUnix>true</TargetsUnix>
        <TargetsLinux>true</TargetsLinux>
        <PackageTargetRuntime>linux-corert</PackageTargetRuntime>
      </PropertyGroup>
    </When>
    <When Condition="'$(OSGroup)'=='OSX'">
      <PropertyGroup>
        <TargetsUnix>true</TargetsUnix>
        <TargetsOSX>true</TargetsOSX>
        <PackageTargetRuntime>osx-corert</PackageTargetRuntime>
      </PropertyGroup>
    </When>
    <When Condition="'$(OSGroup)'=='FreeBSD'">
      <PropertyGroup>
        <TargetsUnix>true</TargetsUnix>
        <TargetsFreeBSD>true</TargetsFreeBSD>
      </PropertyGroup>
    </When>
    <When Condition="'$(OSGroup)'=='NetBSD'">
      <PropertyGroup>
        <TargetsUnix>true</TargetsUnix>
        <TargetsNetBSD>true</TargetsNetBSD>
      </PropertyGroup>
    </When>
    <Otherwise>
      <PropertyGroup>
        <ConfigurationErrorMsg>$(ConfigurationErrorMsg);Unknown OSGroup [$(OSGroup)] specificed in your project.</ConfigurationErrorMsg>
      </PropertyGroup>
    </Otherwise>
  </Choose>

  <!-- Set up various other constants -->
  <PropertyGroup>
    <DefineConstants>CORERT;$(DefineConstants)</DefineConstants>
  </PropertyGroup>
  <PropertyGroup Condition="'$(TargetsWindows)'=='true'">
    <DefineConstants>PLATFORM_WINDOWS;$(DefineConstants)</DefineConstants>
  </PropertyGroup>
  <PropertyGroup Condition="'$(TargetsUnix)'=='true'">
    <DefineConstants>PLATFORM_UNIX;$(DefineConstants)</DefineConstants>
  </PropertyGroup>
  <PropertyGroup Condition="'$(TargetsOSX)'=='true'">
    <DefineConstants>PLATFORM_OSX;$(DefineConstants)</DefineConstants>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Platform)' == 'x64'">
    <DefineConstants>AMD64;BIT64;$(DefineConstants)</DefineConstants>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Platform)' == 'x86'">
    <DefineConstants>X86;BIT32;$(DefineConstants)</DefineConstants>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Platform)' == 'arm'">
    <DefineConstants>ARM;BIT32;$(DefineConstants)</DefineConstants>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Platform)' == 'armel'">
    <DefineConstants>ARM;BIT32;$(DefineConstants)</DefineConstants>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Platform)' == 'arm64'">
    <DefineConstants>ARM64;BIT64;$(DefineConstants)</DefineConstants>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Platform)' == 'wasm'">
    <DefineConstants>WASM;BIT32;$(DefineConstants)</DefineConstants>
  </PropertyGroup>

  <PropertyGroup>
    <PrereleaseResolveNuGetPackages>true</PrereleaseResolveNuGetPackages>
    <NuGetTargetMoniker Condition="'$(NuGetTargetFramework)' == ''">.NETCoreApp,Version=v2.1</NuGetTargetMoniker>
    <BuildPackageLibraryReferences>false</BuildPackageLibraryReferences>
  </PropertyGroup>

  <PropertyGroup>
    <!-- Don't run tests if we're building another platform's binaries on Windows -->
    <SkipTests Condition="'$(SkipTests)'=='' and ('$(OsEnvironment)'=='Windows_NT' and '$(TargetsWindows)'!='true')">true</SkipTests>
  </PropertyGroup>

  <PropertyGroup>
    <!-- On Windows fallback to ILAsm from the framework for now -->
    <IlasmToolPath Condition="'$(OSEnvironment)'=='Windows_NT'">%WINDIR%\Microsoft.NET\Framework\v4.0.30319\ilasm.exe</IlasmToolPath>
  </PropertyGroup>

  <!-- Use Roslyn Compilers to build -->
  <Import Project="$(RoslynPropsFile)" Condition="Exists('$(RoslynPropsFile)')" />
</Project>