<commit_before>﻿using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Security.Cryptography;
using System.Security.Cryptography.Pkcs;
using System.Security.Cryptography.X509Certificates;
using Difi.SikkerDigitalPost.Klient.Domene.Entiteter.Interface;
using Difi.SikkerDigitalPost.Klient.Domene.Entiteter.Post;
using Difi.SikkerDigitalPost.Klient.Utilities;

namespace Difi.SikkerDigitalPost.Klient.Internal.AsicE
{
    internal class AsiceArchive : ISoapVedlegg
    {
        public AsiceArchive(X509Certificate2 cryptographicCertificate, GuidUtility guidUtility, IEnumerable<AsiceAttachableProcessor> asiceAttachableProcessors, params IAsiceAttachable[] asiceAttachables)
        {
            CryptographicCertificate = cryptographicCertificate;
            GuidUtility = guidUtility;
            AsiceAttachableProcessors = asiceAttachableProcessors;
            AsiceAttachables = asiceAttachables;
            UnencryptedBytes = CreateZipFile();
        }

        internal byte[] UnencryptedBytes { get; }

        public long UnzippedContentBytesCount
        {
            get { return AsiceAttachables.Aggregate(0L, (current, asiceAttachable) => current + asiceAttachable.Bytes.Length); }
        }

        public IAsiceAttachable[] AsiceAttachables { get; }

        private GuidUtility GuidUtility { get; }

        public IEnumerable<AsiceAttachableProcessor> AsiceAttachableProcessors { get; }

        private X509Certificate2 CryptographicCertificate { get; }

        public string Filnavn => "post.asice.zip";

        public string Innholdstype => "application/cms";

        public string ContentId => GuidUtility.DokumentpakkeId;

        public string TransferEncoding => "binary";

        public byte[] Bytes => EncryptedBytes(UnencryptedBytes);

        private byte[] EncryptedBytes(byte[] bytes)
        {
            var contentInfo = new ContentInfo(bytes);
            var encryptAlgoOid = new Oid("2.16.840.172.16.58.3.1.42"); // AES-256-CBC            
            var envelopedCms = new EnvelopedCms(contentInfo, new AlgorithmIdentifier(encryptAlgoOid));
            var recipient = new CmsRecipient(CryptographicCertificate);
            envelopedCms.Encrypt(recipient);
            return envelopedCms.Encode();
        }

        private byte[] CreateZipFile()
        {
            var stream = new MemoryStream();
            using (var archive = new ZipArchive(stream, ZipArchiveMode.Create))
            {
                foreach (var asiceAttachable in AsiceAttachables)
                {
                    if (asiceAttachable is Dokument)
                    {
                        AddFilesToArchive(archive, ((Dokument) asiceAttachable).FilnavnRådata, asiceAttachable.Bytes);
                    }
                    else
                    {
                        AddFilesToArchive(archive, asiceAttachable.Filnavn, asiceAttachable.Bytes);
                    }
                }
            }

            var zipFile = stream.ToArray();
            SendArchiveThroughBundleProcessors(zipFile);
            return zipFile;
        }

        private void SendArchiveThroughBundleProcessors(byte[] archiveBytes)
        {
            foreach (var documentBundleProcessor in AsiceAttachableProcessors)
            {
                try
                {<commit_msg>Lukker stream for AsicE<commit_after>﻿using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Security.Cryptography;
using System.Security.Cryptography.Pkcs;
using System.Security.Cryptography.X509Certificates;
using Difi.SikkerDigitalPost.Klient.Domene.Entiteter.Interface;
using Difi.SikkerDigitalPost.Klient.Domene.Entiteter.Post;
using Difi.SikkerDigitalPost.Klient.Utilities;

namespace Difi.SikkerDigitalPost.Klient.Internal.AsicE
{
    internal class AsiceArchive : ISoapVedlegg
    {
        public AsiceArchive(X509Certificate2 cryptographicCertificate, GuidUtility guidUtility,
            IEnumerable<AsiceAttachableProcessor> asiceAttachableProcessors, params IAsiceAttachable[] asiceAttachables)
        {
            CryptographicCertificate = cryptographicCertificate;
            GuidUtility = guidUtility;
            AsiceAttachableProcessors = asiceAttachableProcessors;
            AsiceAttachables = asiceAttachables;
            UnencryptedBytes = CreateZipFile();
        }

        internal byte[] UnencryptedBytes { get; }

        public long UnzippedContentBytesCount
        {
            get
            {
                return AsiceAttachables.Aggregate(0L,
                    (current, asiceAttachable) => current + asiceAttachable.Bytes.Length);
            }
        }

        public IAsiceAttachable[] AsiceAttachables { get; }

        private GuidUtility GuidUtility { get; }

        public IEnumerable<AsiceAttachableProcessor> AsiceAttachableProcessors { get; }

        private X509Certificate2 CryptographicCertificate { get; }

        public string Filnavn => "post.asice.zip";

        public string Innholdstype => "application/cms";

        public string ContentId => GuidUtility.DokumentpakkeId;

        public string TransferEncoding => "binary";

        public byte[] Bytes => EncryptedBytes(UnencryptedBytes);

        private byte[] EncryptedBytes(byte[] bytes)
        {
            var contentInfo = new ContentInfo(bytes);
            var encryptAlgoOid = new Oid("2.16.840.1.101.3.4.1.42"); // AES-256-CBC            
            var envelopedCms = new EnvelopedCms(contentInfo, new AlgorithmIdentifier(encryptAlgoOid));
            var recipient = new CmsRecipient(CryptographicCertificate);
            envelopedCms.Encrypt(recipient);
            return envelopedCms.Encode();
        }

        private byte[] CreateZipFile()
        {
            var stream = new MemoryStream();
            using (stream)
            {
                using (var archive = new ZipArchive(stream, ZipArchiveMode.Create))
                {
                    foreach (var asiceAttachable in AsiceAttachables)
                    {
                        AddFilesToArchive(archive, asiceAttachable is Dokument
                            ? ((Dokument) asiceAttachable).FilnavnRådata
                            : asiceAttachable.Filnavn, asiceAttachable.Bytes);
                    }
                }
            }
            
            var zipFile = stream.ToArray();
            SendArchiveThroughBundleProcessors(zipFile);
            return zipFile;
        }

        private void SendArchiveThroughBundleProcessors(byte[] archiveBytes)
        {
            foreach (var documentBundleProcessor in AsiceAttachableProcessors)
            {
                try
                {
{'fraction_non_alphanumeric': 0.07358351729212656, 'fraction_numerical': 0.009124356144223694, 'mean_word_length': 2.2751807228915664, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, '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': '7389800', 'n_tokens_mistral': 1936, 'n_tokens_neox': 1789, 'n_words': 341}