using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CredScanRegexes
{
    class Program
    {
        static void Main(string[] args)
        {
            var extractor = new CredScanPatternExtractor();
            var version = extractor.GetCredScanVersion();

            StringBuilder sb = new StringBuilder();
            string tab = "                ";
            foreach (var (name, pattern) in extractor.GetPatterns())
            {
                sb.Append($"{tab}// {name}\n");

                var processedPattern = PatternProcessor.Convert(name, pattern);
                sb.Append($"{tab}  @\"{processedPattern.Prematch}\" // pre-match\n");
                sb.Append($"{tab}+ @\"{processedPattern.Match}\" // match\n");
                sb.Append($"{tab}+ @\"{processedPattern.Postmatch}\", // post-match\n");
                sb.Append("\n");
            }

            Console.WriteLine(string.Format(
                Program.fileTemplate,
                sb.ToString(),
                version));
        }

        private static string fileTemplate = @"// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
//
// THIS FILE IS GENERATED CODE.
// DO NOT EDIT.
// YOUR EDITS MAY BE LOST.
//
// Generated by tools/CredScanRegexes/CredScanRegexes.csproj
// from CredScan version {1}

using System.Collections.Generic;

namespace Microsoft.VisualStudio.Services.Agent
{{
    internal static partial class AdditionalMaskingRegexes
    {{
        public static IEnumerable<string> CredScanPatterns => credScanPatterns;

        // Each pattern or set of patterns has a comment mentioning
        // which CredScan policy it came from. In CredScan, if a pattern
        // contains a named group, then that named group is considered the
        // sensitive part.
        // 
        // For the agent, we don't want to mask the non-sensitive parts, so
        // we wrap lookbehind and lookahead non-match groups around those
        // parts which aren't in the named group.
        // 
        // The non-matching parts are pulled out into separate string
        // literals to make them easier to manually examine.
        private static IEnumerable<string> credScanPatterns =
            new List<string>()
            {{
{0}            }};
    }}
}}";
    }
}
