<commit_before>@@setlocal
@@set POWERSHELL_BAT_ARGS=%*
@@if defined POWERSHELL_BAT_ARGS set POWERSHELL_BAT_ARGS=%POWERSHELL_BAT_ARGS:"=\"%
@@powershell.exe -Command Invoke-Expression $('$args=@(^&{$args} %POWERSHELL_BAT_ARGS%);'+[String]::Join([char]10, $((Get-Content '%~f0') -notmatch '^^@@'))) & goto :EOF

Function Main($rootPath, $name)
{
    $fullPath = "$rootPath\$name";
    $exists = Test-Path $fullPath;
    if (!$exists)
    {
        New-Item $fullPath -Type Directory | Out-Null;
    }

    $projects = CreateProjects $name;
    WriteProjects $fullPath $projects;
    WriteStyleCopSettings "$fullPath\StyleCop.settings";
    WriteSolutionFile "$fullPath\$name.sln" $projects;
}

Function CreateProjects($name)
{
    $app = CreateProject "$name.App" "source" $false;
    $core = CreateProject "$name.Core" "source" $false;
    $test = CreateProject "$name.Test.Unit" "test" $true;

    $app.ProjectReferences += $core;
    $test.ProjectReferences += $core;

    return ($app, $core, $test);
}

Function CreateProject($name, $folderName, $isUnitTest)
{
    $path = "$folderName\$name\$name.csproj";
    $properties = 
    @{
        "Name" = $name;
        "Path" = $path;
        "Id" = [guid]::NewGuid();
        "IsUnitTest" = $isUnitTest;
        "ProjectReferences" = @();
    };

    return New-Object PSObject -Property $properties;
}

Function WriteProjects($rootPath, [psobject[]]$projects)
{
    foreach ($project in $projects)
    {
        $file = New-Object -Type "System.IO.FileInfo" -ArgumentList ("$rootPath\" + $project.Path);
        Write-Host "Writing project file '$file'...";
        $parentDir = $file.Directory;
        if (!$parentDir.Exists)
        {
            $parentDir.Create();
        }

        "-- TODO --" | Out-File $file.FullName -Encoding "UTF8";
    }
}

Function WriteSolutionFile($fullPath, [psobject[]]$projects)
{
    Write-Host "Writing solution file '$fullPath'...";
    $headerText = @"

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Express 2013 for Windows Desktop
VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1

"@;
    $projectsText = "";
    $globalSectionText = @"
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|Any CPU = Debug|Any CPU
		Release|Any CPU = Release|Any CPU
	EndGlobalSection
	GlobalSection(ProjectConfigurationPlatforms) = postSolution

"@;
    $footerText = @"
	EndGlobalSection
	GlobalSection(SolutionProperties) = preSolution
		HideSolutionNode = FALSE
	EndGlobalSection
EndGlobal
"@;

    foreach ($project in $projects)
    {
        $name = $project.Name;
        $path = $project.Path;
        $id = $project.Id.ToString("B").ToUpperInvariant();
        $projectsText += @"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "$name", "$path", "$id"
EndProject

"@;
        $globalSectionText += @"
		$id.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		$id.Debug|Any CPU.Build.0 = Debug|Any CPU
		$id.Release|Any CPU.ActiveCfg = Release|Any CPU
		$id.Release|Any CPU.Build.0 = Release|Any CPU

"@;
    }

    $text = $headerText + $projectsText + $globalSectionText + $footerText;
    $text = $text -Replace "`n", "`r`n";
    $text | Out-File $fullPath -Encoding "UTF8";
}

Function WriteStyleCopSettings($fullPath)
{
    Write-Host "Writing StyleCop settings file '$fullPath'...";
    $text = @"
<StyleCopSettings Version="105">
  <GlobalSettings><commit_msg>Add basic csproj generation<commit_after>@@setlocal
@@set POWERSHELL_BAT_ARGS=%*
@@if defined POWERSHELL_BAT_ARGS set POWERSHELL_BAT_ARGS=%POWERSHELL_BAT_ARGS:"=\"%
@@powershell.exe -Command Invoke-Expression $('$args=@(^&{$args} %POWERSHELL_BAT_ARGS%);'+[String]::Join([char]10, $((Get-Content '%~f0') -notmatch '^^@@'))) & goto :EOF


$ProjectConsole = 1;
$ProjectLibrary = 2;
$ProjectUnitTest = 3;

Function Main($rootPath, $name)
{
    $fullPath = "$rootPath\$name";
    $exists = Test-Path $fullPath;
    if (!$exists)
    {
        New-Item $fullPath -Type Directory | Out-Null;
    }

    $projects = CreateProjects $name;
    WriteProjects $name $fullPath $projects;
    WriteStyleCopSettings "$fullPath\StyleCop.settings";
    WriteSolutionFile "$fullPath\$name.sln" $projects;
}

Function CreateProjects($name)
{
    $app = CreateProject "$name.App" "source" $ProjectConsole "Program.cs";
    $core = CreateProject "$name.Core" "source" $ProjectLibrary "Class1.cs";
    $test = CreateProject "$name.Test.Unit" "test" $ProjectUnitTest "Test1.cs";

    $app.ProjectReferences += $core;
    $test.ProjectReferences += $core;

    return ($app, $core, $test);
}

Function CreateProject($name, $folderName, $type, $fileToInclude)
{
    $path = "$folderName\$name\$name.csproj";
    $properties = 
    @{
        "Name" = $name;
        "Path" = $path;
        "Id" = [guid]::NewGuid().ToString("B").ToUpperInvariant();
        "ProjectType" = $type;
        "ProjectReferences" = @();
        "FileToInclude" = $fileToInclude;
    };

    return New-Object PSObject -Property $properties;
}

Function WriteProjects($solutionName, $rootPath, [psobject[]]$projects)
{
    foreach ($project in $projects)
    {
        $file = New-Object -Type "System.IO.FileInfo" -ArgumentList ("$rootPath\" + $project.Path);
        Write-Host "Writing project file '$file'...";
        $parentDir = $file.Directory;
        if (!$parentDir.Exists)
        {
            $parentDir.Create();
        }

        GetProjectText $solutionName $project | Out-File $file.FullName -Encoding "UTF8";
    }
}

Function GetProjectText($solutionName, $project)
{
    $id = $project.Id;
    $name = $project.Name;
    $afterHeaderText = "";
    $fileToInclude = $project.FileToInclude;
    $filesText = "";
    if ($project.ProjectType -eq $ProjectConsole)
    {
        $outputType = "Exe";
        $rootNamespace = $solutionName;
        $afterHeaderText +=
@'
    <PlatformTarget>AnyCPU</PlatformTarget>
    <Prefer32Bit>false</Prefer32Bit>

'@;
    }
    elseif ($project.ProjectType -eq $ProjectLibrary)
    {
        $outputType = "Library";
        $rootNamespace = $solutionName;
    }
    else
    {
        $outputType = "Library";
        $rootNamespace = "$solutionName.Test.Unit";
    }

    $headerText =
@'
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
'@;
    $headerText +=
@"
    <ProjectGuid>$id</ProjectGuid>
    <OutputType>$outputType</OutputType>
    <RootNamespace>$rootNamespace</RootNamespace>
    <AssemblyName>$name</AssemblyName>

"@;

    $headerText +=
@'
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
    <OutputPath>..\..\bin\$(Configuration)\</OutputPath>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <StyleCopTreatErrorsAsWarnings>false</StyleCopTreatErrorsAsWarnings>

'@;

    $afterHeaderText +=
@'
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <DefineConstants>TRACE</DefineConstants>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Core" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Properties\AssemblyInfo.cs" />

'@;

    $filesText =
@"
    <Compile Include="$fileToInclude" />
  </ItemGroup>

"@;

    $projectReferencesText = "";
    if ($project.ProjectReferences.Length -gt 0)
    {
        $projectReferencesText += @'
  <ItemGroup>

'@;
        foreach ($refProject in $project.ProjectReferences)
        {
            $includePath = GetIncludePath $project.Path $refProject.Path;
            $refName = $refProject.Name;
            $refId = $refProject.Id;
            $projectReferencesText +=
@"
    <ProjectReference Include="$includePath">
      <Project>$refId</Project>
      <Name>$refName</Name>
    </ProjectReference>

"@;
        }

        $projectReferencesText += @'
  </ItemGroup>

'@;
    }

    $footerText =
@'
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <Import Project="$(MSBuildExtensionsPath)\StyleCop\v4.7\StyleCop.Targets" />
</Project>
'@;

    $text = $headerText + $afterHeaderText + $filesText + $projectReferencesText + $footerText;
    $text = $text -Replace "`n", "`r`n";
    return $text;
}

Function GetIncludePath($source, $dest)
{
    $tree = @{};
    $current = $tree;
    $depth = 0;
    foreach ($part in $source.Split('\'))
    {
        $current[$part] = @{};
        $current = $current[$part];
        ++$depth;
    }

    $current = $tree;
    $includePathParts = @();
    $stillMatches = $true;
    foreach ($part in $dest.Split('\'))
    {
        if ($stillMatches)
        {
            if ($current.ContainsKey($part))
            {
                --$depth;
                $current = $current[$part];
            }
            else
            {
                $stillMatches = $false;
                for ($i = 1; $i -lt $depth; ++$i)
                {
                    $includePathParts += "..";
                }
            }
        }

        if (!$stillMatches)
        {
            $includePathParts += $part;
        }
    }

    return [string]::Join('\', $includePathParts);
}

Function WriteSolutionFile($fullPath, [psobject[]]$projects)
{
    Write-Host "Writing solution file '$fullPath'...";
    $headerText =
@"

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Express 2013 for Windows Desktop
VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1

"@;
    $projectsText = "";
    $globalSectionText =
@"
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|Any CPU = Debug|Any CPU
		Release|Any CPU = Release|Any CPU
	EndGlobalSection
	GlobalSection(ProjectConfigurationPlatforms) = postSolution

"@;
    $footerText =
@"
	EndGlobalSection
	GlobalSection(SolutionProperties) = preSolution
		HideSolutionNode = FALSE
	EndGlobalSection
EndGlobal
"@;

    foreach ($project in $projects)
    {
        $name = $project.Name;
        $path = $project.Path;
        $id = $project.Id;
        $projectsText +=
@"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "$name", "$path", "$id"
EndProject

"@;
        $globalSectionText += 
@"
		$id.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		$id.Debug|Any CPU.Build.0 = Debug|Any CPU
		$id.Release|Any CPU.ActiveCfg = Release|Any CPU
		$id.Release|Any CPU.Build.0 = Release|Any CPU

"@;
    }

    $text = $headerText + $projectsText + $globalSectionText + $footerText;
    $text = $text -Replace "`n", "`r`n";
    $text | Out-File $fullPath -Encoding "UTF8";
}

Function WriteStyleCopSettings($fullPath)
{
    Write-Host "Writing StyleCop settings file '$fullPath'...";
    $text =
@"
<StyleCopSettings Version="105">
  <GlobalSettings>
{'fraction_non_alphanumeric': 0.15983357891999653, 'fraction_numerical': 0.011614804541908642, 'mean_word_length': 3.2972067039106143, 'pattern_counts': {'":': 0, '<': 79, '<?xml version=': 1, '>': 79, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6781228', 'n_tokens_mistral': 3913, 'n_tokens_neox': 3657, 'n_words': 676}