<commit_before>﻿using System;
using Microsoft.Build.Framework;
using NuGet.Protocol.Core.Types;
using System.Collections.Generic;
using System.Threading;
using NuGet.Protocol;
using NuGet.Protocol.Core.v2;
using NuGet.Configuration;
using System.Diagnostics;
using System.IO;
using NuGet.Packaging;
using NuGet.Packaging.Core;
using System.Text;
using System.Net.Http;
using Com.Blackducksoftware.Integration.Hub.Bdio.Simple;
using Com.Blackducksoftware.Integration.Hub.Bdio.Simple.Model;
using Com.Blackducksoftware.Integration.Hub.Common.Net;
using Com.Blackducksoftware.Integration.Hub.Common.Net.Global;
using Com.Blackducksoftware.Integration.Hub.Common.Net.Rest;
using Com.Blackducksoftware.Integration.Hub.Common.Net.Dataservices;
using Com.Blackducksoftware.Integration.Hub.Common.Net.Api;
using Com.Blackducksoftware.Integration.Hub.Common.Net.Items;
using Com.Blackducksoftware.Integration.Hub.Common.Net.Model.CodeLocation;
using Com.Blackducksoftware.Integration.Hub.Common.Net.Model.PolicyStatus;
using Com.Blackducksoftware.Integration.Hub.Common.Net.Model.ScanStatus;
using Com.Blackducksoftware.Integration.Hub.Common.Net.Model.Enums;
using Com.Blackducksoftware.Integration.Hub.Common.Net.Model.Project;
using System.Reflection;
using System.Xml;
using System.Xml.Linq;

namespace Com.Blackducksoftware.Integration.Hub.Nuget
{
    public class BuildBOMTask : Microsoft.Build.Utilities.Task
    {
        [Required]
        public string HubUrl { get; set; }
        [Required]
        public string HubUsername { get; set; }
        [Required]
        public string HubPassword { get; set; }
        [Required]
        public string PackagesRepoUrl { get; set; }

        public int HubTimeout { get; set; } = 120;
        public string HubProjectName { get; set; }
        public string HubVersionName { get; set; }

        public string HubProxyHost { get; set; }
        public string HubProxyPort { get; set; }
        public string HubProxyUsername { get; set; }
        public string HubProxyPassword { get; set; }

        public int HubScanTimeout { get; set; } = 300;
        public string OutputDirectory { get; set; }
        public string ExcludedModules { get; set; } = "";
        public bool HubIgnoreFailure { get; set; } = false;
        public bool CreateFlatDependencyList { get; set; } = false;
        public bool CreateHubBdio { get; set; } = true;
        public bool DeployHubBdio { get; set; } = true;
        public bool CreateHubReport { get; set; } = false;
        public bool CheckPolicies { get; set; } = false;

        public string PackagesConfigPath { get; set; }

        public bool WaitForDeployment = false;
        private RestConnection RestConnection;

        // Dataservices
        private CodeLocationDataService CodeLocationDataService;
        private ScanSummariesDataService ScanSummariesDataService;
        private DeployBdioDataService DeployBdioDataService;
        private ProjectDataService ProjectDataService;
        private PolicyDataService PolicyDataService;
        private RiskReportDataService RiskReportDataService;

        // Helper properties
        private string BdioId;
        private bool initAssemblies = true;

        private void Setup()
        {
            LoadPackagesXML();
            // Estabilish authenticated connection
            HubServerConfig hubServerConfig = BuildHubServerConfig();
            RestConnection restConnection = new CredentialsResetConnection(hubServerConfig);
            Setup(restConnection);
        }

        public void LoadPackagesXML()
        {
            if (initAssemblies)
            {
                Dictionary<string, string> assemblyBindingMap = new Dictionary<string, string>(30);
                // need to provide the same functionality as the assembly binding refereence in app.config programatically for a task.  
                // Use the assembly resolve handler to achieve this. 
                assemblyBindingMap["Newtonsoft.Json"] = "10.0.0.0";
                assemblyBindingMap["NuGet.Protocol.Core.Types"] = "4.0.0.0";
                assemblyBindingMap["NuGet.Configuration"] = "4.0.0.0";
                
                foreach(string assemblyName in assemblyBindingMap.Keys)
                {
                    LoadLocalAssembly(assemblyName, assemblyBindingMap[assemblyName]);
                }

                initAssemblies = false;
            }
        }

        public void LoadLocalAssembly(string shortName, string version)
        {
            ResolveEventHandler handler = null;

            handler = (object sender, ResolveEventArgs args) =>
            {                
                AssemblyName requestedAssembly = new AssemblyName(args.Name);

                if(requestedAssembly.Name != shortName)
                {
                    return null;
                }

                requestedAssembly.Version = new Version(version);
                AppDomain.CurrentDomain.AssemblyResolve -= handler;

                Log.LogMessage(MessageImportance.High,"Loading assembly Name: {0}, Resolving Assembly {1}", args.Name, requestedAssembly);

                return Assembly.Load(requestedAssembly);
            };
            AppDomain.CurrentDomain.AssemblyResolve += handler;
        }

        public void Setup(RestConnection restConnection)
        {
            RestConnection = restConnection;

            // Create required dataservices
            CodeLocationDataService = new CodeLocationDataService(RestConnection);
            ScanSummariesDataService = new ScanSummariesDataService(RestConnection);
            DeployBdioDataService = new DeployBdioDataService(RestConnection);
            ProjectDataService = new ProjectDataService(RestConnection);
            PolicyDataService = new PolicyDataService(RestConnection);
            RiskReportDataService = new RiskReportDataService(RestConnection);

            // Set helper properties
            BdioPropertyHelper bdioPropertyHelper = new BdioPropertyHelper();
            BdioId = bdioPropertyHelper.CreateBdioId(HubProjectName, HubVersionName);
        }

        public override bool Execute()
        {
            try
            {
                Setup();
                ExecuteTask();
            }
            catch (Exception ex)
            {
                if (HubIgnoreFailure)
                {
                    Log.LogMessage(MessageImportance.High, "Error executing Build BOM task on project {0}, cause: {1}", HubProjectName ,ex);
                    return true;
                }
                else
                {
                    Log.LogError("Error executing Build BOM task on project {0}, cause: {1}", HubProjectName, ex);
                }
            }
            finally
            {
                RestConnection.Dispose();
            }
            return true;
        }

        public void ExecuteTask()
        {
            if (IsExcluded())
            {
                Log.LogMessage("Project {0} excluded from task", HubProjectName);
            }
            else
            {
                // Creates output directory if it doesn't already exist
                Directory.CreateDirectory(OutputDirectory);

                // Define output files
                string bdioFilePath = $"{OutputDirectory}/{HubProjectName}.jsonld";
                string flatListFilePath = $"{OutputDirectory}/{HubProjectName}_flat.txt";

                // Execute task functionality
                if (CreateFlatDependencyList)
                {
                    string[] externalIds = CreateFlatList().ToArray();<commit_msg>fail the build but don't throw and exception just log error.<commit_after>﻿using System;
using Microsoft.Build.Framework;
using NuGet.Protocol.Core.Types;
using System.Collections.Generic;
using System.Threading;
using NuGet.Protocol;
using NuGet.Protocol.Core.v2;
using NuGet.Configuration;
using System.Diagnostics;
using System.IO;
using NuGet.Packaging;
using NuGet.Packaging.Core;
using System.Text;
using System.Net.Http;
using Com.Blackducksoftware.Integration.Hub.Bdio.Simple;
using Com.Blackducksoftware.Integration.Hub.Bdio.Simple.Model;
using Com.Blackducksoftware.Integration.Hub.Common.Net;
using Com.Blackducksoftware.Integration.Hub.Common.Net.Global;
using Com.Blackducksoftware.Integration.Hub.Common.Net.Rest;
using Com.Blackducksoftware.Integration.Hub.Common.Net.Dataservices;
using Com.Blackducksoftware.Integration.Hub.Common.Net.Api;
using Com.Blackducksoftware.Integration.Hub.Common.Net.Items;
using Com.Blackducksoftware.Integration.Hub.Common.Net.Model.CodeLocation;
using Com.Blackducksoftware.Integration.Hub.Common.Net.Model.PolicyStatus;
using Com.Blackducksoftware.Integration.Hub.Common.Net.Model.ScanStatus;
using Com.Blackducksoftware.Integration.Hub.Common.Net.Model.Enums;
using Com.Blackducksoftware.Integration.Hub.Common.Net.Model.Project;
using System.Reflection;
using System.Xml;
using System.Xml.Linq;

namespace Com.Blackducksoftware.Integration.Hub.Nuget
{
    public class BuildBOMTask : Microsoft.Build.Utilities.Task
    {
        [Required]
        public string HubUrl { get; set; }
        [Required]
        public string HubUsername { get; set; }
        [Required]
        public string HubPassword { get; set; }
        [Required]
        public string PackagesRepoUrl { get; set; }

        public int HubTimeout { get; set; } = 120;
        public string HubProjectName { get; set; }
        public string HubVersionName { get; set; }

        public string HubProxyHost { get; set; }
        public string HubProxyPort { get; set; }
        public string HubProxyUsername { get; set; }
        public string HubProxyPassword { get; set; }

        public int HubScanTimeout { get; set; } = 300;
        public string OutputDirectory { get; set; }
        public string ExcludedModules { get; set; } = "";
        public bool HubIgnoreFailure { get; set; } = false;
        public bool CreateFlatDependencyList { get; set; } = false;
        public bool CreateHubBdio { get; set; } = true;
        public bool DeployHubBdio { get; set; } = true;
        public bool CreateHubReport { get; set; } = false;
        public bool CheckPolicies { get; set; } = false;

        public string PackagesConfigPath { get; set; }

        public bool WaitForDeployment = false;
        private RestConnection RestConnection;

        // Dataservices
        private CodeLocationDataService CodeLocationDataService;
        private ScanSummariesDataService ScanSummariesDataService;
        private DeployBdioDataService DeployBdioDataService;
        private ProjectDataService ProjectDataService;
        private PolicyDataService PolicyDataService;
        private RiskReportDataService RiskReportDataService;

        // Helper properties
        private string BdioId;
        private bool initAssemblies = true;

        private void Setup()
        {
            LoadPackagesXML();
            // Estabilish authenticated connection
            HubServerConfig hubServerConfig = BuildHubServerConfig();
            RestConnection restConnection = new CredentialsResetConnection(hubServerConfig);
            Setup(restConnection);
        }

        public void LoadPackagesXML()
        {
            if (initAssemblies)
            {
                Dictionary<string, string> assemblyBindingMap = new Dictionary<string, string>(30);
                // need to provide the same functionality as the assembly binding refereence in app.config programatically for a task.  
                // Use the assembly resolve handler to achieve this. 
                assemblyBindingMap["Newtonsoft.Json"] = "10.0.0.0";
                assemblyBindingMap["NuGet.Protocol.Core.Types"] = "4.0.0.0";
                assemblyBindingMap["NuGet.Configuration"] = "4.0.0.0";
                
                foreach(string assemblyName in assemblyBindingMap.Keys)
                {
                    LoadLocalAssembly(assemblyName, assemblyBindingMap[assemblyName]);
                }

                initAssemblies = false;
            }
        }

        public void LoadLocalAssembly(string shortName, string version)
        {
            ResolveEventHandler handler = null;

            handler = (object sender, ResolveEventArgs args) =>
            {                
                AssemblyName requestedAssembly = new AssemblyName(args.Name);

                if(requestedAssembly.Name != shortName)
                {
                    return null;
                }

                requestedAssembly.Version = new Version(version);
                AppDomain.CurrentDomain.AssemblyResolve -= handler;

                Log.LogMessage(MessageImportance.High,"Loading assembly Name: {0}, Resolving Assembly {1}", args.Name, requestedAssembly);

                return Assembly.Load(requestedAssembly);
            };
            AppDomain.CurrentDomain.AssemblyResolve += handler;
        }

        public void Setup(RestConnection restConnection)
        {
            RestConnection = restConnection;

            // Create required dataservices
            CodeLocationDataService = new CodeLocationDataService(RestConnection);
            ScanSummariesDataService = new ScanSummariesDataService(RestConnection);
            DeployBdioDataService = new DeployBdioDataService(RestConnection);
            ProjectDataService = new ProjectDataService(RestConnection);
            PolicyDataService = new PolicyDataService(RestConnection);
            RiskReportDataService = new RiskReportDataService(RestConnection);

            // Set helper properties
            BdioPropertyHelper bdioPropertyHelper = new BdioPropertyHelper();
            BdioId = bdioPropertyHelper.CreateBdioId(HubProjectName, HubVersionName);
        }

        public override bool Execute()
        {
            try
            {
                Setup();
                ExecuteTask();
            }
            catch (Exception ex)
            {
                if (HubIgnoreFailure)
                {
                    Log.LogMessage(MessageImportance.High, "Error executing Build BOM task on project {0}, cause: {1}", HubProjectName ,ex);
                    return true;
                }
                else
                {
                    Log.LogError("Error executing Build BOM task on project {0}, cause: {1}", HubProjectName, ex);
                    return false;
                }
            }
            finally
            {
                RestConnection.Dispose();
            }
            return true;
        }

        public void ExecuteTask()
        {
            if (IsExcluded())
            {
                Log.LogMessage("Project {0} excluded from task", HubProjectName);
            }
            else
            {
                // Creates output directory if it doesn't already exist
                Directory.CreateDirectory(OutputDirectory);

                // Define output files
                string bdioFilePath = $"{OutputDirectory}/{HubProjectName}.jsonld";
                string flatListFilePath = $"{OutputDirectory}/{HubProjectName}_flat.txt";

                // Execute task functionality
                if (CreateFlatDependencyList)
                {
                    string[] externalIds = CreateFlatList().ToArray();
{'fraction_non_alphanumeric': 0.07930922124470512, 'fraction_numerical': 0.0037797328119908765, 'mean_word_length': 2.1654290429042904, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 6, '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': '7529395', 'n_tokens_mistral': 3929, 'n_tokens_neox': 3736, 'n_words': 895}