<commit_before>﻿using Microsoft.WindowsAzure.Commands.Common.Extensions.DSC.Exceptions;
using Microsoft.WindowsAzure.Commands.Utilities.Common;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Auth;
using Microsoft.WindowsAzure.Storage.Blob;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Management.Automation;
using Newtonsoft.Json;


namespace Microsoft.WindowsAzure.Commands.Common.Extensions.DSC.Publish
{
    public class DscExtensionPublishCmdletCommonBase : AzurePSCmdlet
    {
        //Publish
        private const string CreateArchiveParameterSetName = "CreateArchive";
        private const string UploadArchiveParameterSetName = "UploadArchive";
        private readonly List<string> _temporaryFilesToDelete = new List<string>();
        private readonly List<string> _temporaryDirectoriesToDelete = new List<string>();

        public void ValidatePsVersion()
        {
            using (System.Management.Automation.PowerShell powershell = System.Management.Automation.PowerShell.Create())
            {
                powershell.AddScript("$PSVersionTable.PSVersion.Major");
                int major = powershell.Invoke<int>().FirstOrDefault();
                if (major < DscExtensionCmdletConstants.MinMajorPowerShellVersion)
                {
                    ThrowTerminatingError(
                        new ErrorRecord(
                            new InvalidOperationException(
                                string.Format(
                                CultureInfo.CurrentUICulture, 
                                Properties.Resources.PublishVMDscExtensionRequiredPsVersion, 
                                DscExtensionCmdletConstants.MinMajorPowerShellVersion, 
                                major)),
                            "InvalidPowerShellVersion",
                            ErrorCategory.InvalidOperation,
                            null));
                }
            }
        }

        public void ValidateConfigurationPath(String configurationPath, String paramaterSetName)
        {
            if (!File.Exists(configurationPath))
            {
                ThrowInvalidArgumentError(
                    Properties.Resources.PublishVMDscExtensionUploadArchiveConfigFileNotExist,
                    configurationPath);
            }

            var configurationFileExtension = Path.GetExtension(configurationPath);

            if (paramaterSetName == UploadArchiveParameterSetName)
            {
                if (!DscExtensionCmdletConstants.UploadArchiveAllowedFileExtensions.Contains(Path.GetExtension(configurationFileExtension)))
                {
                    ThrowInvalidArgumentError(Properties.Resources.PublishVMDscExtensionUploadArchiveConfigFileInvalidExtension, configurationPath);
                }
            }
            else if (paramaterSetName == CreateArchiveParameterSetName)
            {
                if (!DscExtensionCmdletConstants.CreateArchiveAllowedFileExtensions.Contains(Path.GetExtension(configurationFileExtension)))
                {
                    ThrowInvalidArgumentError(Properties.Resources.PublishVMDscExtensionCreateArchiveConfigFileInvalidExtension, configurationPath);
                }
            }
        }

        public void ValidateConfigurationDataPath(String configurationDataPath)
        {
            if (!File.Exists(configurationDataPath))
            {
                ThrowInvalidArgumentError(
                    Properties.Resources.AzureVMDscCannotFindConfigurationDataFile,
                    configurationDataPath);
            }
            if (string.Compare(
                Path.GetExtension(configurationDataPath),
                ".psd1",
                StringComparison.InvariantCultureIgnoreCase) != 0)
            {
                ThrowInvalidArgumentError(Properties.Resources.AzureVMDscInvalidConfigurationDataFile);
            }
        }

        public string CreateConfigurationArchive(
            String configurationPath,
            String configurationDataPath,
            String[] additionalPath,
            String configurationArchivePath,
            Boolean force,
            Boolean skipDependencyDetection,
            String parameterSetName)
        {
            var metadata = new Dictionary<string, object>();
            // Create a temporary directory for uploaded zip file
            var tempZipFolder = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            WriteVerbose(String.Format(
                CultureInfo.CurrentUICulture, 
                Properties.Resources.PublishVMDscExtensionTempFolderVerbose, 
                tempZipFolder));
            Directory.CreateDirectory(tempZipFolder);
            _temporaryDirectoriesToDelete.Add(tempZipFolder);

            // Copy Configuration
            var configurationName = Path.GetFileName(configurationPath);
            var configurationDestination = Path.Combine(tempZipFolder, configurationName);
            CopyFileToZipFolder(configurationPath, configurationDestination);

            //copy configuration data if available
            if (configurationDataPath != null)
            {
                var configurationDataName = Path.GetFileName(configurationDataPath);
                var configurationDataDestination = Path.Combine(tempZipFolder, configurationDataName);
                metadata.Add("ConfigurationData",configurationDataName);
                CopyFileToZipFolder(configurationDataPath, configurationDataDestination);    
            }
            
            //copy additional content if available
            if (additionalPath != null && additionalPath.Length > 0)
            {
                var additionalContentMetadata = new List<string>();
                foreach (var contentPath in additionalPath)
                {
                    CopyAdditionalContent(contentPath, tempZipFolder, additionalContentMetadata);
                }
                metadata.Add("AdditionalContent", additionalContentMetadata);
            }

            //Copy required modules when -SkipDependencyDetection switch is not present
            if (!skipDependencyDetection)
            {
                var metadataModules = CopyRequiredModules(configurationPath, tempZipFolder);
                if (metadataModules != null)
                {
                    metadata.Add("Modules", metadataModules);
                }
            } 

            //copy metadata info
            var metadataJson = JsonConvert.SerializeObject(metadata);
            const string metadataFileName = "dscmetadata.json";
            var metadataDestPath = Path.Combine(tempZipFolder, metadataFileName);
            File.WriteAllText(metadataDestPath, metadataJson);

            //
            // Zip the directory
            //<commit_msg>Add dscmetadata.json only when config data,modules or additional content exist<commit_after>﻿using Microsoft.WindowsAzure.Commands.Common.Extensions.DSC.Exceptions;
using Microsoft.WindowsAzure.Commands.Utilities.Common;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Auth;
using Microsoft.WindowsAzure.Storage.Blob;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Management.Automation;
using Newtonsoft.Json;


namespace Microsoft.WindowsAzure.Commands.Common.Extensions.DSC.Publish
{
    public class DscExtensionPublishCmdletCommonBase : AzurePSCmdlet
    {
        //Publish
        private const string CreateArchiveParameterSetName = "CreateArchive";
        private const string UploadArchiveParameterSetName = "UploadArchive";
        private readonly List<string> _temporaryFilesToDelete = new List<string>();
        private readonly List<string> _temporaryDirectoriesToDelete = new List<string>();

        public void ValidatePsVersion()
        {
            using (System.Management.Automation.PowerShell powershell = System.Management.Automation.PowerShell.Create())
            {
                powershell.AddScript("$PSVersionTable.PSVersion.Major");
                int major = powershell.Invoke<int>().FirstOrDefault();
                if (major < DscExtensionCmdletConstants.MinMajorPowerShellVersion)
                {
                    ThrowTerminatingError(
                        new ErrorRecord(
                            new InvalidOperationException(
                                string.Format(
                                CultureInfo.CurrentUICulture, 
                                Properties.Resources.PublishVMDscExtensionRequiredPsVersion, 
                                DscExtensionCmdletConstants.MinMajorPowerShellVersion, 
                                major)),
                            "InvalidPowerShellVersion",
                            ErrorCategory.InvalidOperation,
                            null));
                }
            }
        }

        public void ValidateConfigurationPath(String configurationPath, String paramaterSetName)
        {
            if (!File.Exists(configurationPath))
            {
                ThrowInvalidArgumentError(
                    Properties.Resources.PublishVMDscExtensionUploadArchiveConfigFileNotExist,
                    configurationPath);
            }

            var configurationFileExtension = Path.GetExtension(configurationPath);

            if (paramaterSetName == UploadArchiveParameterSetName)
            {
                if (!DscExtensionCmdletConstants.UploadArchiveAllowedFileExtensions.Contains(Path.GetExtension(configurationFileExtension)))
                {
                    ThrowInvalidArgumentError(Properties.Resources.PublishVMDscExtensionUploadArchiveConfigFileInvalidExtension, configurationPath);
                }
            }
            else if (paramaterSetName == CreateArchiveParameterSetName)
            {
                if (!DscExtensionCmdletConstants.CreateArchiveAllowedFileExtensions.Contains(Path.GetExtension(configurationFileExtension)))
                {
                    ThrowInvalidArgumentError(Properties.Resources.PublishVMDscExtensionCreateArchiveConfigFileInvalidExtension, configurationPath);
                }
            }
        }

        public void ValidateConfigurationDataPath(String configurationDataPath)
        {
            if (!File.Exists(configurationDataPath))
            {
                ThrowInvalidArgumentError(
                    Properties.Resources.AzureVMDscCannotFindConfigurationDataFile,
                    configurationDataPath);
            }
            if (string.Compare(
                Path.GetExtension(configurationDataPath),
                ".psd1",
                StringComparison.InvariantCultureIgnoreCase) != 0)
            {
                ThrowInvalidArgumentError(Properties.Resources.AzureVMDscInvalidConfigurationDataFile);
            }
        }

        public string CreateConfigurationArchive(
            String configurationPath,
            String configurationDataPath,
            String[] additionalPath,
            String configurationArchivePath,
            Boolean force,
            Boolean skipDependencyDetection,
            String parameterSetName)
        {
            var metadata = new Dictionary<string, object>();
            // Create a temporary directory for uploaded zip file
            var tempZipFolder = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            WriteVerbose(String.Format(
                CultureInfo.CurrentUICulture, 
                Properties.Resources.PublishVMDscExtensionTempFolderVerbose, 
                tempZipFolder));
            Directory.CreateDirectory(tempZipFolder);
            _temporaryDirectoriesToDelete.Add(tempZipFolder);

            // Copy Configuration
            var configurationName = Path.GetFileName(configurationPath);
            var configurationDestination = Path.Combine(tempZipFolder, configurationName);
            CopyFileToZipFolder(configurationPath, configurationDestination);

            //copy configuration data if available
            if (configurationDataPath != null)
            {
                var configurationDataName = Path.GetFileName(configurationDataPath);
                var configurationDataDestination = Path.Combine(tempZipFolder, configurationDataName);
                metadata.Add("ConfigurationData",configurationDataName);
                CopyFileToZipFolder(configurationDataPath, configurationDataDestination);    
            }
            
            //copy additional content if available
            if (additionalPath != null && additionalPath.Length > 0)
            {
                var additionalContentMetadata = new List<string>();
                foreach (var contentPath in additionalPath)
                {
                    CopyAdditionalContent(contentPath, tempZipFolder, additionalContentMetadata);
                }
                metadata.Add("AdditionalContent", additionalContentMetadata);
            }

            //Copy required modules when -SkipDependencyDetection switch is not present
            if (!skipDependencyDetection)
            {
                var metadataModules = CopyRequiredModules(configurationPath, tempZipFolder);
                if (metadataModules != null && metadataModules.Count > 0)
                {
                    metadata.Add("Modules", metadataModules);
                }
            } 

            //copy metadata info only when modules/additional content/configuration data exist
            if (metadata.Count > 0)
            {
                var metadataJson = JsonConvert.SerializeObject(metadata);
                const string metadataFileName = "dscmetadata.json";
                var metadataDestPath = Path.Combine(tempZipFolder, metadataFileName);
                File.WriteAllText(metadataDestPath, metadataJson);    
            }
            
            //
            // Zip the directory
            //
{'fraction_non_alphanumeric': 0.06443408223823655, 'fraction_numerical': 0.0005652112477038293, 'mean_word_length': 2.018767327788441, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, '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': '4337102', 'n_tokens_mistral': 3074, 'n_tokens_neox': 2898, 'n_words': 538}