/// <summary>
        /// Used to generate a test token based on the the data in the given TokenRestrictionTemplate.
        /// </summary>
        /// <param name="tokenTemplate">TokenRestrictionTemplate describing the token to generate</param>
        /// <param name="signingKeyToUse">Specifies the specific signing key to use.  If null, the PrimaryVerificationKey from the template is used.</param>
        /// <param name="keyIdForContentKeyIdentifierClaim">Key Identifier used as the value of the Content Key Identifier Claim.  Ignored if no TokenClaim with a ClaimType of TokenClaim.ContentKeyIdentifierClaimType is not present</param>
        /// <param name="tokenExpiration">The Date and Time when the token expires.  Expired tokens are considered invalid by the Key Delivery Service.</param>
        /// <returns>A Simple Web Token (SWT)</returns>
        public static string GenerateTestToken(TokenRestrictionTemplate tokenTemplate, TokenVerificationKey signingKeyToUse = null, Guid?keyIdForContentKeyIdentifierClaim = null, DateTime?tokenExpiration = null)
        {
            if (tokenTemplate == null)
            {
                throw new ArgumentNullException("tokenTemplate");
            }

            if (signingKeyToUse == null)
            {
                signingKeyToUse = tokenTemplate.PrimaryVerificationKey;
            }

            if (!tokenExpiration.HasValue)
            {
                tokenExpiration = DateTime.UtcNow.AddMinutes(10);
            }

            StringBuilder builder = new StringBuilder();

            foreach (TokenClaim claim in tokenTemplate.RequiredClaims)
            {
                string claimValue = claim.ClaimValue;
                if (claim.ClaimType == TokenClaim.ContentKeyIdentifierClaimType)
                {
                    claimValue = keyIdForContentKeyIdentifierClaim.ToString();
                }

                builder.AppendFormat("{0}={1}&", HttpUtility.UrlEncode(claim.ClaimType), HttpUtility.UrlEncode(claimValue));
            }

            builder.AppendFormat("Audience={0}&", HttpUtility.UrlEncode(tokenTemplate.Audience.AbsoluteUri));
            builder.AppendFormat("ExpiresOn={0}&", GenerateTokenExpiry(tokenExpiration.Value));
            builder.AppendFormat("Issuer={0}", HttpUtility.UrlEncode(tokenTemplate.Issuer.AbsoluteUri));

            SymmetricVerificationKey signingKey = (SymmetricVerificationKey)signingKeyToUse;

            using (var signatureAlgorithm = new HMACSHA256(signingKey.KeyValue))
            {
                byte[] unsignedTokenAsBytes = Encoding.UTF8.GetBytes(builder.ToString());

                byte[] signatureBytes = signatureAlgorithm.ComputeHash(unsignedTokenAsBytes);

                string signatureString = Convert.ToBase64String(signatureBytes);

                builder.Insert(0, "Bearer=");
                builder.AppendFormat("&HMACSHA256={0}", HttpUtility.UrlEncode(signatureString));
            }

            return(builder.ToString());
        }
        private void DoDynamicEncryptionWithAES(List<IAsset> SelectedAssets, AddDynamicEncryptionFrame1 form1, AddDynamicEncryptionFrame2_AESKeyConfig form2, AddDynamicEncryptionFrame3_AESDelivery form3_AES, List<AddDynamicEncryptionFrame4> form4list, bool DisplayUI)
        {
            bool ErrorCreationKey = false;
            string aeskey = string.Empty;
            bool firstkeycreation = true;
            Uri aeslaurl = null;
            IContentKey formerkey = null;
            bool reusekey = false;

            if (!form2.ContentKeyRandomGeneration)
            {
                aeskey = form2.AESContentKey;
                aeslaurl = form3_AES.AESLaUrl;
            }


            if (!form2.ContentKeyRandomGeneration && (form2.AESKeyId != null))  // user want to manually enter the cryptography data and key if providedd 
            {
                // if the key already exists in the account (same key id), let's 
                formerkey = SelectedAssets.FirstOrDefault().GetMediaContext().ContentKeys.Where(c => c.Id == Constants.ContentKeyIdPrefix + form2.AESKeyId.ToString()).FirstOrDefault();
                if (formerkey != null)
                {
                    if (DisplayUI && MessageBox.Show("A Content key with the same Key Id exists already in the account.\nDo you want to try to replace it?\n(If not, the existing key will be used)", "Content key Id", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                    {
                        // user wants to replace the key
                        try
                        {
                            formerkey.Delete();
                        }
                        catch (Exception e)
                        {
                            // Add useful information to the exception
                            TextBoxLogWriteLine("There is a problem when deleting the content key {0}.", formerkey.Id, true);
                            TextBoxLogWriteLine(e);
                            TextBoxLogWriteLine("The former key will be reused.", true);
                            reusekey = true;
                        }
                    }
                    else
                    {
                        reusekey = true;
                    }
                }
            }



            foreach (IAsset AssetToProcess in SelectedAssets)
            {

                if (AssetToProcess != null)
                {
                    IContentKey contentKey = null;

                    var contentkeys = AssetToProcess.ContentKeys.Where(c => c.ContentKeyType == form1.GetContentKeyType);

                    if (contentkeys.Count() == 0) // no content key existing so we need to create one
                    {
                        ErrorCreationKey = false;


                        if (form3_AES.GetNumberOfAuthorizationPolicyOptions > 0 && (form2.ContentKeyRandomGeneration))
                        // Azure will deliver the license and user want to auto generate the key, so we can create a key with a random content key
                        {
                            try
                            {
                                contentKey = DynamicEncryption.CreateEnvelopeTypeContentKey(AssetToProcess);
                            }
                            catch (Exception e)
                            {
                                // Add useful information to the exception
                                TextBoxLogWriteLine("There is a problem when creating the content key for '{0}'.", AssetToProcess.Name, true);
                                TextBoxLogWriteLine(e);
                                ErrorCreationKey = true;
                            }
                            if (!ErrorCreationKey)
                            {
                                TextBoxLogWriteLine("Created key {0} for asset '{1}'.", contentKey.Id, AssetToProcess.Name);
                            }
                        }
                        else // user wants to deliver with an external key server or want to provide some cryptography, so let's create the key based on what the user input
                        {
                            if ((firstkeycreation && !reusekey) || form2.AESKeyId == null) // if we need to generate a new key id for each asset
                            {
                                try
                                {
                                    if ((!form2.ContentKeyRandomGeneration) && !string.IsNullOrEmpty(aeskey)) // user provides custom crypto (key, or key id)
                                    {
                                        contentKey = DynamicEncryption.CreateEnvelopeTypeContentKey(AssetToProcess, Convert.FromBase64String(aeskey), form2.AESKeyId);
                                    }
                                    else // content key if random. Perhaps key id has been provided
                                    {
                                        contentKey = DynamicEncryption.CreateEnvelopeTypeContentKey(AssetToProcess, form2.AESKeyId);
                                    }
                                }
                                catch (Exception e)
                                {
                                    // Add useful information to the exception
                                    TextBoxLogWriteLine("There is a problem when creating the content key for asset '{0}'.", AssetToProcess.Name, true);
                                    TextBoxLogWriteLine(e);
                                    ErrorCreationKey = true;
                                }
                                if (!ErrorCreationKey)
                                {
                                    TextBoxLogWriteLine("Created key {0} for asset '{1}'.", contentKey.Id, AssetToProcess.Name);
                                }

                                formerkey = contentKey;
                                firstkeycreation = false;
                            }
                            else
                            {
                                contentKey = formerkey;
                                AssetToProcess.ContentKeys.Add(contentKey);
                                AssetToProcess.Update();
                                TextBoxLogWriteLine("Reusing key {0} for the asset {1} ", contentKey.Id, AssetToProcess.Name);
                            }
                        }

                    }
                    else if (form3_AES.GetNumberOfAuthorizationPolicyOptions == 0)  // user wants to deliver with an external key server but the key exists already !
                    {
                        TextBoxLogWriteLine("Warning for asset '{0}'. A AES key already exists. You need to make sure that your external key server can deliver the key for this asset.", AssetToProcess.Name, true);
                    }

                    else // let's use existing content key
                    {
                        contentKey = contentkeys.FirstOrDefault();
                        TextBoxLogWriteLine("Existing key {0} will be used for asset {1}.", contentKey.Id, AssetToProcess.Name);
                    }


                    if (form3_AES.GetNumberOfAuthorizationPolicyOptions > 0) // AES Key and delivery from Azure Media Services
                    {

                        // let's create the Authorization Policy
                        IContentKeyAuthorizationPolicy contentKeyAuthorizationPolicy = _context.
                                       ContentKeyAuthorizationPolicies.
                                       CreateAsync("Authorization Policy").Result;

                        // Associate the content key authorization policy with the content key.
                        contentKey.AuthorizationPolicyId = contentKeyAuthorizationPolicy.Id;
                        contentKey = contentKey.UpdateAsync().Result;


                        foreach (var form3 in form4list)
                        {
                            IContentKeyAuthorizationPolicyOption policyOption = null;
                            ErrorCreationKey = false;
                            try
                            {
                                switch (form3.GetKeyRestrictionType)
                                {
                                    case ContentKeyRestrictionType.Open:

                                        policyOption = DynamicEncryption.AddOpenAuthorizationPolicyOption(contentKey, ContentKeyDeliveryType.BaselineHttp, null, _context);
                                        TextBoxLogWriteLine("Created Open authorization policy for the asset {0} ", contentKey.Id, AssetToProcess.Name);
                                        contentKeyAuthorizationPolicy.Options.Add(policyOption);
                                        break;

                                    case ContentKeyRestrictionType.TokenRestricted:
                                        TokenVerificationKey mytokenverifkey = null;
                                        string OpenIdDoc = null;
                                        switch (form3.GetDetailedTokenType)
                                        {
                                            case ExplorerTokenType.SWT:
                                            case ExplorerTokenType.JWTSym:
                                                mytokenverifkey = new SymmetricVerificationKey(Convert.FromBase64String(form3.SymmetricKey));
                                                break;

                                            case ExplorerTokenType.JWTOpenID:
                                                OpenIdDoc = form3.GetOpenIdDiscoveryDocument;
                                                break;

                                            case ExplorerTokenType.JWTX509:
                                                mytokenverifkey = new X509CertTokenVerificationKey(form3.GetX509Certificate);
                                                break;
                                        }

                                        policyOption = DynamicEncryption.AddTokenRestrictedAuthorizationPolicyAES(contentKey, form3.GetAudience, form3.GetIssuer, form3.GetTokenRequiredClaims, form3.AddContentKeyIdentifierClaim, form3.GetTokenType, form3.GetDetailedTokenType, mytokenverifkey, _context, OpenIdDoc);
                                        TextBoxLogWriteLine("Created Token AES authorization policy for the asset {0} ", contentKey.Id, AssetToProcess.Name);
                                        contentKeyAuthorizationPolicy.Options.Add(policyOption);

                                        if (form3.GetDetailedTokenType != ExplorerTokenType.JWTOpenID) // not possible to create a test token if OpenId is used
                                        {
                                            // let display a test token
                                            X509SigningCredentials signingcred = null;
                                            if (form3.GetDetailedTokenType == ExplorerTokenType.JWTX509)
                                            {
                                                signingcred = new X509SigningCredentials(form3.GetX509Certificate);
                                            }

                                            _context = Program.ConnectAndGetNewContext(_credentials); // otherwise cache issues with multiple options
                                            DynamicEncryption.TokenResult testToken = DynamicEncryption.GetTestToken(AssetToProcess, _context, form1.GetContentKeyType, signingcred, policyOption.Id);
                                            TextBoxLogWriteLine("The authorization test token for option #{0} ({1} with Bearer) is:\n{2}", form4list.IndexOf(form3), form3.GetTokenType.ToString(), Constants.Bearer + testToken.TokenString);
                                            System.Windows.Forms.Clipboard.SetText(Constants.Bearer + testToken.TokenString);

                                        }
                                        break;

                                    default:
                                        break;
                                }
                            }
                            catch (Exception e)
                            {
                                // Add useful information to the exception
                                TextBoxLogWriteLine("There is a problem when creating the authorization policy for '{0}'.", AssetToProcess.Name, true);
                                TextBoxLogWriteLine(e);
                                ErrorCreationKey = true;
                            }

                        }
                        contentKeyAuthorizationPolicy.Update();
                    }

                    // Let's create the Asset Delivery Policy now
                    IAssetDeliveryPolicy DelPol = null;
                    string name = string.Format("AssetDeliveryPolicy {0} ({1})", form1.GetContentKeyType.ToString(), form1.GetAssetDeliveryProtocol.ToString());

                    try
                    {
                        DelPol = DynamicEncryption.CreateAssetDeliveryPolicyAES(AssetToProcess, contentKey, form1.GetAssetDeliveryProtocol, name, _context, aeslaurl);
                        TextBoxLogWriteLine("Created asset delivery policy {0} for asset {1}.", DelPol.AssetDeliveryPolicyType, AssetToProcess.Name);
                    }
                    catch (Exception e)
                    {
                        TextBoxLogWriteLine("There is a problem when creating the delivery policy for '{0}'.", AssetToProcess.Name, true);
                        TextBoxLogWriteLine(e);
                    }
                }
            }
        }
        private void DoDynamicEncryptionWithAES(List<IAsset> SelectedAssets, AddDynamicEncryptionFrame1 form1, AddDynamicEncryptionFrame2_AESKeyConfig form2, List<AddDynamicEncryptionFrame3> form3list)
        {
            bool Error = false;
            string aeskey = string.Empty;
            if (!form2.ContentKeyRandomGeneration)
            {
                aeskey = form2.AESContentKey;
            }

            foreach (IAsset AssetToProcess in SelectedAssets)
            {

                if (AssetToProcess != null)
                {
                    IContentKey contentKey = null;

                    var contentkeys = AssetToProcess.ContentKeys.Where(c => c.ContentKeyType == form1.GetContentKeyType);
                    if (contentkeys.Count() == 0) // no content key existing so we need to create one
                    {
                        Error = false;
                        try
                        {
                            if ((!form2.ContentKeyRandomGeneration) && !string.IsNullOrEmpty(aeskey)) // user has to provide the key
                            {
                                contentKey = DynamicEncryption.CreateEnvelopeTypeContentKey(AssetToProcess, Convert.FromBase64String(aeskey));
                            }
                            else
                            {
                                contentKey = DynamicEncryption.CreateEnvelopeTypeContentKey(AssetToProcess);
                            }
                        }
                        catch (Exception e)
                        {
                            // Add useful information to the exception
                            TextBoxLogWriteLine("There is a problem when creating the content key for '{0}'.", AssetToProcess.Name, true);
                            TextBoxLogWriteLine(e);
                            Error = true;
                        }
                        if (!Error)
                        {
                            TextBoxLogWriteLine("Created key {0} for the asset {1} ", contentKey.Id, AssetToProcess.Name);
                        }

                    }

                    else // let's use existing content key
                    {
                        contentKey = contentkeys.FirstOrDefault();
                        TextBoxLogWriteLine("Existing key {0} will be used for asset {1}.", contentKey.Id, AssetToProcess.Name);
                    }


                    // let's create the Authorization Policy
                    IContentKeyAuthorizationPolicy contentKeyAuthorizationPolicy = _context.
                                   ContentKeyAuthorizationPolicies.
                                   CreateAsync("My Authorization Policy").Result;

                    // Associate the content key authorization policy with the content key.
                    contentKey.AuthorizationPolicyId = contentKeyAuthorizationPolicy.Id;
                    contentKey = contentKey.UpdateAsync().Result;


                    foreach (var form3 in form3list)
                    {
                        IContentKeyAuthorizationPolicyOption policyOption = null;
                        Error = false;
                        try
                        {
                            switch (form3.GetKeyRestrictionType)
                            {
                                case ContentKeyRestrictionType.Open:

                                    policyOption = DynamicEncryption.AddOpenAuthorizationPolicyOption(contentKey, ContentKeyDeliveryType.BaselineHttp, null, _context);
                                    TextBoxLogWriteLine("Created Open authorization policy for the asset {0} ", contentKey.Id, AssetToProcess.Name);
                                    contentKeyAuthorizationPolicy.Options.Add(policyOption);
                                    break;

                                case ContentKeyRestrictionType.TokenRestricted:
                                    TokenVerificationKey mytokenverifkey = null;
                                    string OpenIdDoc = null;
                                    switch (form3.GetDetailedTokenType)
                                    {
                                        case ExplorerTokenType.SWT:
                                        case ExplorerTokenType.JWTSym:
                                            mytokenverifkey = new SymmetricVerificationKey(Convert.FromBase64String(form3.SymmetricKey));
                                            break;

                                        case ExplorerTokenType.JWTOpenID:
                                            OpenIdDoc = form3.GetOpenIdDiscoveryDocument;
                                            break;

                                        case ExplorerTokenType.JWTX509:
                                            mytokenverifkey = new X509CertTokenVerificationKey(form3.GetX509Certificate);
                                            break;
                                    }

                                    policyOption = DynamicEncryption.AddTokenRestrictedAuthorizationPolicyAES(contentKey, form3.GetAudience, form3.GetIssuer, form3.GetTokenRequiredClaims, form3.AddContentKeyIdentifierClaim, form3.GetTokenType, form3.GetDetailedTokenType, mytokenverifkey, _context, OpenIdDoc);
                                    TextBoxLogWriteLine("Created Token AES authorization policy for the asset {0} ", contentKey.Id, AssetToProcess.Name);
                                    contentKeyAuthorizationPolicy.Options.Add(policyOption);

                                    if (form3.GetDetailedTokenType != ExplorerTokenType.JWTOpenID) // not possible to create a test token if OpenId is used
                                    {
                                        // let display a test token
                                        X509SigningCredentials signingcred = null;
                                        if (form3.GetDetailedTokenType == ExplorerTokenType.JWTX509)
                                        {
                                            signingcred = new X509SigningCredentials(form3.GetX509Certificate);
                                        }

                                        _context = Program.ConnectAndGetNewContext(_credentials); // otherwise cache issues with multiple options
                                        DynamicEncryption.TokenResult testToken = DynamicEncryption.GetTestToken(AssetToProcess, _context, form1.GetContentKeyType, signingcred, policyOption.Id);
                                        TextBoxLogWriteLine("The authorization test token for option #{0} ({1} with Bearer) is:\n{2}", form3list.IndexOf(form3), form3.GetTokenType.ToString(), Constants.Bearer + testToken.TokenString);
                                        System.Windows.Forms.Clipboard.SetText(Constants.Bearer + testToken.TokenString);

                                    }
                                    break;

                                default:
                                    break;
                            }
                        }
                        catch (Exception e)
                        {
                            // Add useful information to the exception
                            TextBoxLogWriteLine("There is a problem when creating the authorization policy for '{0}'.", AssetToProcess.Name, true);
                            TextBoxLogWriteLine(e);
                            Error = true;
                        }

                    }
                    contentKeyAuthorizationPolicy.Update();

                    // Let's create the Asset Delivery Policy now
                    IAssetDeliveryPolicy DelPol = null;
                    string name = string.Format("AssetDeliveryPolicy {0} ({1})", form1.GetContentKeyType.ToString(), form1.GetAssetDeliveryProtocol.ToString());

                    try
                    {
                        DelPol = DynamicEncryption.CreateAssetDeliveryPolicyAES(AssetToProcess, contentKey, form1.GetAssetDeliveryProtocol, name, _context);
                        TextBoxLogWriteLine("Created asset delivery policy {0} for asset {1}.", DelPol.AssetDeliveryPolicyType, AssetToProcess.Name);
                    }
                    catch (Exception e)
                    {
                        TextBoxLogWriteLine("There is a problem when creating the delivery policy for '{0}'.", AssetToProcess.Name, true);
                        TextBoxLogWriteLine(e);
                    }
                }
            }
        }
        private void DoDynamicEncryptionAndKeyDeliveryWithCENC(List<IAsset> SelectedAssets, AddDynamicEncryptionFrame1 form1, AddDynamicEncryptionFrame2_CENCKeyConfig form2_CENC, AddDynamicEncryptionFrame3_CENCDelivery form3_CENC, List<AddDynamicEncryptionFrame4> form4list, List<AddDynamicEncryptionFrame5_PlayReadyLicense> form5PlayReadyLicenseList, List<AddDynamicEncryptionFrame6_WidevineLicense> form6WidevineLicenseList, bool DisplayUI)
        {
            bool ErrorCreationKey = false;
            bool reusekey = false;
            bool firstkeycreation = true;
            IContentKey formerkey = null;

            if (!form2_CENC.ContentKeyRandomGeneration && (form2_CENC.KeyId != null))  // user want to manually enter the cryptography data and key if providedd 
            {
                // if the key already exists in the account (same key id), let's 
                formerkey = SelectedAssets.FirstOrDefault().GetMediaContext().ContentKeys.Where(c => c.Id == Constants.ContentKeyIdPrefix + form2_CENC.KeyId.ToString()).FirstOrDefault();
                if (formerkey != null)
                {
                    if (DisplayUI && MessageBox.Show("A Content key with the same Key Id exists already in the account.\nDo you want to try to replace it?\n(If not, the existing key will be used)", "Content key Id", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                    {
                        // user wants to replace the key
                        try
                        {
                            formerkey.Delete();
                        }
                        catch (Exception e)
                        {
                            // Add useful information to the exception
                            TextBoxLogWriteLine("There is a problem when deleting the content key {0}.", formerkey.Id, true);
                            TextBoxLogWriteLine(e);
                            TextBoxLogWriteLine("The former key will be reused.", true);
                            reusekey = true;
                        }
                    }
                    else
                    {
                        reusekey = true;
                    }
                }
            }


            foreach (IAsset AssetToProcess in SelectedAssets)
            {
                if (AssetToProcess != null)
                {
                    IContentKey contentKey = null;
                    var contentkeys = AssetToProcess.ContentKeys.Where(c => c.ContentKeyType == form1.GetContentKeyType);
                    // special case, no dynamic encryption, goal is to setup key auth policy. CENC key is selected

                    if (contentkeys.Count() == 0) // no content key existing so we need to create one
                    {
                        ErrorCreationKey = false;

                        //    if ((form3_CENC.GetNumberOfAuthorizationPolicyOptionsPlayReady + form3_CENC.GetNumberOfAuthorizationPolicyOptionsWidevine) > 0 && form2_CENC.ContentKeyRandomGeneration)
                        //// Azure will deliver the PR or WV license and user wants to auto generate the key, so we can create a key with a random content key

                        if (!reusekey && ((form3_CENC.GetNumberOfAuthorizationPolicyOptionsPlayReady + form3_CENC.GetNumberOfAuthorizationPolicyOptionsWidevine) > 0 || form2_CENC.ContentKeyRandomGeneration))

                        // Azure will deliver the PR or WV license or user wants to auto generate the key, so we can create a key with a random content key
                        {
                            try
                            {
                                contentKey = DynamicEncryption.CreateCommonTypeContentKey(AssetToProcess, _context);
                            }
                            catch (Exception e)
                            {
                                // Add useful information to the exception
                                TextBoxLogWriteLine("There is a problem when creating the content key for '{0}'.", AssetToProcess.Name, true);
                                TextBoxLogWriteLine(e);
                                ErrorCreationKey = true;
                            }
                            if (!ErrorCreationKey)
                            {
                                TextBoxLogWriteLine("Created key {0} for asset '{1}'.", contentKey.Id, AssetToProcess.Name);
                            }

                        }
                        else // user wants to deliver with an external PlayReady or Widevine server or want to provide the key, so let's create the key based on what the user input
                        {
                            // if the key does not exist in the account (same key id), let's create it
                            if ((firstkeycreation && !reusekey) || form2_CENC.KeyId == null) // if we need to generate a new key id for each asset
                            {
                                if (form2_CENC.KeySeed != null) // seed has been given
                                {
                                    Guid keyid = (form2_CENC.KeyId == null) ? Guid.NewGuid() : (Guid)form2_CENC.KeyId;
                                    byte[] bytecontentkey = CommonEncryption.GeneratePlayReadyContentKey(Convert.FromBase64String(form2_CENC.KeySeed), keyid);
                                    try
                                    {
                                        contentKey = DynamicEncryption.CreateCommonTypeContentKey(AssetToProcess, _context, keyid, bytecontentkey);
                                    }
                                    catch (Exception e)
                                    {
                                        // Add useful information to the exception
                                        TextBoxLogWriteLine("There is a problem when creating the content key for '{0}'.", AssetToProcess.Name, true);
                                        TextBoxLogWriteLine(e);
                                        ErrorCreationKey = true;
                                    }
                                    if (!ErrorCreationKey)
                                    {
                                        TextBoxLogWriteLine("Created key {0} for the asset {1} ", contentKey.Id, AssetToProcess.Name);
                                    }
                                }
                                else // no seed given, so content key has been setup
                                {
                                    try
                                    {
                                        contentKey = DynamicEncryption.CreateCommonTypeContentKey(AssetToProcess, _context, (Guid)form2_CENC.KeyId, Convert.FromBase64String(form2_CENC.CENCContentKey));
                                    }
                                    catch (Exception e)
                                    {
                                        // Add useful information to the exception
                                        TextBoxLogWriteLine("There is a problem when creating the content key for asset '{0}'.", AssetToProcess.Name, true);
                                        TextBoxLogWriteLine(e);
                                        ErrorCreationKey = true;
                                    }
                                    if (!ErrorCreationKey)
                                    {
                                        TextBoxLogWriteLine("Created key {0} for asset '{1}'.", contentKey.Id, AssetToProcess.Name);
                                    }

                                }
                                formerkey = contentKey;
                                firstkeycreation = false;
                            }
                            else
                            {
                                contentKey = formerkey;
                                AssetToProcess.ContentKeys.Add(contentKey);
                                AssetToProcess.Update();
                                TextBoxLogWriteLine("Reusing key {0} for the asset {1} ", contentKey.Id, AssetToProcess.Name);
                            }
                        }
                    }
                    else if (false)//form1.PlayReadyPackaging form3_CENC.GetNumberOfAuthorizationPolicyOptionsPlayReady == 0 || form3_CENC.GetNumberOfAuthorizationPolicyOptionsWidevine == 0)
                                   // TO DO ? : if user wants to deliver license from external servers
                                   // user wants to deliver license with an external PlayReady and/or Widevine server but the key exists already !
                    {
                        TextBoxLogWriteLine("Warning for asset '{0}'. A CENC key already exists. You need to make sure that your external PlayReady or Widevine server can deliver the license for this asset.", AssetToProcess.Name, true);
                    }
                    else // let's use existing content key
                    {
                        contentKey = contentkeys.FirstOrDefault();
                        TextBoxLogWriteLine("Existing key '{0}' will be used for asset '{1}'.", contentKey.Id, AssetToProcess.Name);
                    }
                    if ((form3_CENC.GetNumberOfAuthorizationPolicyOptionsPlayReady + form3_CENC.GetNumberOfAuthorizationPolicyOptionsWidevine) > 0) // PlayReady/Widevine license and delivery from Azure Media Services
                    {
                        // let's create the Authorization Policy
                        IContentKeyAuthorizationPolicy contentKeyAuthorizationPolicy = _context.
                                       ContentKeyAuthorizationPolicies.
                                       CreateAsync("Authorization Policy").Result;

                        // Associate the content key authorization policy with the content key.
                        contentKey.AuthorizationPolicyId = contentKeyAuthorizationPolicy.Id;
                        contentKey = contentKey.UpdateAsync().Result;

                        foreach (var form4 in form4list)
                        { // for each option

                            string PlayReadyLicenseDeliveryConfig = null;
                            string WidevineLicenseDeliveryConfig = null;
                            bool ItIsAPlayReadyOption = form4list.IndexOf(form4) < form3_CENC.GetNumberOfAuthorizationPolicyOptionsPlayReady;

                            if (ItIsAPlayReadyOption)
                            { // user wants to define a PlayReady license for this option
                              // let's build the PlayReady license template

                                ErrorCreationKey = false;
                                try
                                {
                                    PlayReadyLicenseDeliveryConfig = form5PlayReadyLicenseList[form4list.IndexOf(form4)].GetLicenseTemplate;
                                }
                                catch (Exception e)
                                {
                                    // Add useful information to the exception
                                    TextBoxLogWriteLine("There is a problem when configuring the PlayReady license template.", true);
                                    TextBoxLogWriteLine(e);
                                    ErrorCreationKey = true;
                                }
                            }
                            else
                            { // user wants to define a Widevine license for this option

                                WidevineLicenseDeliveryConfig =
                                    form6WidevineLicenseList[form4list.IndexOf(form4) - form3_CENC.GetNumberOfAuthorizationPolicyOptionsPlayReady]
                                    .GetWidevineConfiguration(contentKey.GetKeyDeliveryUrl(ContentKeyDeliveryType.Widevine).ToString());
                            }

                            if (!ErrorCreationKey)
                            {
                                IContentKeyAuthorizationPolicyOption policyOption = null;
                                try
                                {
                                    switch (form4.GetKeyRestrictionType)
                                    {
                                        case ContentKeyRestrictionType.Open:
                                            if (ItIsAPlayReadyOption)
                                            {
                                                policyOption = DynamicEncryption.AddOpenAuthorizationPolicyOption(contentKey, ContentKeyDeliveryType.PlayReadyLicense, PlayReadyLicenseDeliveryConfig, _context);
                                                TextBoxLogWriteLine("Created PlayReady Open authorization policy for the asset '{0}' ", AssetToProcess.Name);
                                                contentKeyAuthorizationPolicy.Options.Add(policyOption);
                                            }
                                            else // widevine
                                            {
                                                policyOption = DynamicEncryption.AddOpenAuthorizationPolicyOption(contentKey, ContentKeyDeliveryType.Widevine, WidevineLicenseDeliveryConfig, _context);
                                                TextBoxLogWriteLine("Created Widevine Open authorization policy for the asset '{0}' ", AssetToProcess.Name);
                                                contentKeyAuthorizationPolicy.Options.Add(policyOption);
                                            }
                                            break;

                                        case ContentKeyRestrictionType.TokenRestricted:
                                            TokenVerificationKey mytokenverifkey = null;
                                            string OpenIdDoc = null;
                                            switch (form4.GetDetailedTokenType)
                                            {
                                                case ExplorerTokenType.SWT:
                                                case ExplorerTokenType.JWTSym:
                                                    mytokenverifkey = new SymmetricVerificationKey(Convert.FromBase64String(form4.SymmetricKey));
                                                    break;

                                                case ExplorerTokenType.JWTOpenID:
                                                    OpenIdDoc = form4.GetOpenIdDiscoveryDocument;
                                                    break;

                                                case ExplorerTokenType.JWTX509:
                                                    mytokenverifkey = new X509CertTokenVerificationKey(form4.GetX509Certificate);
                                                    break;
                                            }

                                            if (ItIsAPlayReadyOption)
                                            {
                                                policyOption = DynamicEncryption.AddTokenRestrictedAuthorizationPolicyCENC(ContentKeyDeliveryType.PlayReadyLicense, contentKey, form4.GetAudience, form4.GetIssuer, form4.GetTokenRequiredClaims, form4.AddContentKeyIdentifierClaim, form4.GetTokenType, form4.GetDetailedTokenType, mytokenverifkey, _context, PlayReadyLicenseDeliveryConfig, OpenIdDoc);
                                                TextBoxLogWriteLine("Created Token PlayReady authorization policy for the asset '{0}'.", AssetToProcess.Name);
                                            }
                                            else //widevine
                                            {
                                                policyOption = DynamicEncryption.AddTokenRestrictedAuthorizationPolicyCENC(ContentKeyDeliveryType.Widevine, contentKey, form4.GetAudience, form4.GetIssuer, form4.GetTokenRequiredClaims, form4.AddContentKeyIdentifierClaim, form4.GetTokenType, form4.GetDetailedTokenType, mytokenverifkey, _context, WidevineLicenseDeliveryConfig, OpenIdDoc);
                                                TextBoxLogWriteLine("Created Token Widevine authorization policy for the asset '{0}'", AssetToProcess.Name);
                                            }
                                            contentKeyAuthorizationPolicy.Options.Add(policyOption);


                                            if (form4.GetDetailedTokenType != ExplorerTokenType.JWTOpenID) // not possible to create a test token if OpenId is used
                                            {
                                                // let display a test token
                                                X509SigningCredentials signingcred = null;
                                                if (form4.GetDetailedTokenType == ExplorerTokenType.JWTX509)
                                                {
                                                    signingcred = new X509SigningCredentials(form4.GetX509Certificate);
                                                }

                                                _context = Program.ConnectAndGetNewContext(_credentials); // otherwise cache issues with multiple options
                                                DynamicEncryption.TokenResult testToken = DynamicEncryption.GetTestToken(AssetToProcess, _context, form1.GetContentKeyType, signingcred, policyOption.Id);
                                                TextBoxLogWriteLine("The authorization test token for option #{0} ({1} with Bearer) is:\n{2}", form4list.IndexOf(form4), form4.GetTokenType.ToString(), Constants.Bearer + testToken.TokenString);
                                                System.Windows.Forms.Clipboard.SetText(Constants.Bearer + testToken.TokenString);
                                            }
                                            break;

                                        default:
                                            break;
                                    }
                                }
                                catch (Exception e)
                                {
                                    // Add useful information to the exception
                                    TextBoxLogWriteLine("There is a problem when creating the authorization policy for '{0}'.", AssetToProcess.Name, true);
                                    TextBoxLogWriteLine(e);
                                    ErrorCreationKey = true;
                                }
                            }
                        }
                        contentKeyAuthorizationPolicy.Update();
                    }


                    // Let's create the Asset Delivery Policy now
                    if (form1.GetDeliveryPolicyType != AssetDeliveryPolicyType.None && form1.EnableDynEnc)
                    {
                        IAssetDeliveryPolicy DelPol = null;

                        var assetDeliveryProtocol = form1.GetAssetDeliveryProtocol;
                        if (!form1.PlayReadyPackaging && form1.WidevinePackaging)
                        {
                            assetDeliveryProtocol = AssetDeliveryProtocol.Dash;  // only DASH
                        }

                        string name = string.Format("AssetDeliveryPolicy {0} ({1})", form1.GetContentKeyType.ToString(), assetDeliveryProtocol.ToString());
                        ErrorCreationKey = false;

                        try
                        {
                            DelPol = DynamicEncryption.CreateAssetDeliveryPolicyCENC(
                                AssetToProcess,
                                contentKey,
                                form1,
                                name,
                                _context,
                                playreadyAcquisitionUrl: form3_CENC.GetNumberOfAuthorizationPolicyOptionsPlayReady > 0 ? null : form3_CENC.PlayReadyLAurl,
                                playreadyEncodeLAURLForSilverlight: form3_CENC.GetNumberOfAuthorizationPolicyOptionsPlayReady > 0 ? false : form3_CENC.PlayReadyLAurlEncodeForSL,
                                widevineAcquisitionUrl: form3_CENC.GetNumberOfAuthorizationPolicyOptionsWidevine > 0 ? null : form3_CENC.WidevineLAurl
                                );

                            TextBoxLogWriteLine("Created asset delivery policy '{0}' for asset '{1}'.", DelPol.AssetDeliveryPolicyType, AssetToProcess.Name);
                        }
                        catch (Exception e)
                        {
                            TextBoxLogWriteLine("There is a problem when creating the delivery policy for '{0}'.", AssetToProcess.Name, true);
                            TextBoxLogWriteLine(e);
                            ErrorCreationKey = true;
                        }
                    }
                }
            }
        }
        private void DoDynamicEncryptionAndKeyDeliveryWithPlayReady(List<IAsset> SelectedAssets, AddDynamicEncryptionFrame1 form1, AddDynamicEncryptionFrame2_PlayReadyKeyConfig form2_PlayReady, List<AddDynamicEncryptionFrame3> form3list, List<AddDynamicEncryptionFrame4_PlayReadyLicense> form4PlayReadyLicenseList, bool DisplayUI)
        {
            bool ErrorCreationKey = false;
            bool reusekey = false;
            bool firstkeycreation = true;
            IContentKey formerkey = null;

            if (!form2_PlayReady.ContentKeyRandomGeneration)  // user want to manually enter the key and did not provide a seed
            {
                // if the key already exists in the account (same key id), let's 
                formerkey = SelectedAssets.FirstOrDefault().GetMediaContext().ContentKeys.Where(c => c.Id == Constants.ContentKeyIdPrefix + form2_PlayReady.PlayReadyKeyId.ToString()).FirstOrDefault();
                if (formerkey != null)
                {
                    if (DisplayUI && MessageBox.Show("A Content key with the same Key Id exists already in the account.\nDo you want to try to replace it?\n(If not, the existing key will be used)", "Content key Id", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                    {
                        // user wants to replace the key
                        try
                        {
                            formerkey.Delete();
                        }
                        catch (Exception e)
                        {
                            // Add useful information to the exception
                            TextBoxLogWriteLine("There is a problem when deleting the content key {0}.", formerkey.Id, true);
                            TextBoxLogWriteLine(e);
                            TextBoxLogWriteLine("The former key will be reused.", true);
                            reusekey = true;
                        }
                    }
                    else
                    {
                        reusekey = true;
                    }
                }
            }


            foreach (IAsset AssetToProcess in SelectedAssets)
            {
                if (AssetToProcess != null)
                {
                    IContentKey contentKey = null;
                    var contentkeys = AssetToProcess.ContentKeys.Where(c => c.ContentKeyType == form1.GetContentKeyType);
                    // special case, no dynamic encryption, goal is to setup key auth policy. CENC key is selected

                    if (contentkeys.Count() == 0) // no content key existing so we need to create one
                    {
                        ErrorCreationKey = false;

                        if (form1.GetNumberOfAuthorizationPolicyOptions > 0 && (form2_PlayReady.ContentKeyRandomGeneration)) // Azure will deliver the license and user want to auto generate the key, so we can create a key with a random content key
                        {
                            try
                            {
                                contentKey = DynamicEncryption.CreateCommonTypeContentKey(AssetToProcess, _context);
                            }
                            catch (Exception e)
                            {
                                // Add useful information to the exception
                                TextBoxLogWriteLine("There is a problem when creating the content key for '{0}'.", AssetToProcess.Name, true);
                                TextBoxLogWriteLine(e);
                                ErrorCreationKey = true;
                            }
                            if (!ErrorCreationKey)
                            {
                                TextBoxLogWriteLine("Created key {0} for asset '{1}'.", contentKey.Id, AssetToProcess.Name);
                            }

                        }
                        else // user wants to deliver with an external PlayReady server or want to provide the key, so let's create the key based on what the user input
                        {
                            // if the key does not exist in the account (same key id), let's 
                            if (firstkeycreation && !reusekey)
                            {
                                if (!string.IsNullOrEmpty(form2_PlayReady.PlayReadyKeySeed)) // seed has been given
                                {
                                    Guid keyid = (form2_PlayReady.PlayReadyKeyId == null) ? Guid.NewGuid() : (Guid)form2_PlayReady.PlayReadyKeyId;
                                    byte[] bytecontentkey = CommonEncryption.GeneratePlayReadyContentKey(Convert.FromBase64String(form2_PlayReady.PlayReadyKeySeed), keyid);
                                    try
                                    {
                                        contentKey = DynamicEncryption.CreateCommonTypeContentKey(AssetToProcess, _context, keyid, bytecontentkey);
                                    }
                                    catch (Exception e)
                                    {
                                        // Add useful information to the exception
                                        TextBoxLogWriteLine("There is a problem when creating the content key for '{0}'.", AssetToProcess.Name, true);
                                        TextBoxLogWriteLine(e);
                                        ErrorCreationKey = true;
                                    }
                                    if (!ErrorCreationKey)
                                    {
                                        TextBoxLogWriteLine("Created key {0} for the asset {1} ", contentKey.Id, AssetToProcess.Name);
                                    }

                                }
                                else // no seed given, so content key has been setup
                                {
                                    try
                                    {
                                        contentKey = DynamicEncryption.CreateCommonTypeContentKey(AssetToProcess, _context, (Guid)form2_PlayReady.PlayReadyKeyId, Convert.FromBase64String(form2_PlayReady.PlayReadyContentKey));
                                    }
                                    catch (Exception e)
                                    {
                                        // Add useful information to the exception
                                        TextBoxLogWriteLine("There is a problem when creating the content key for asset '{0}'.", AssetToProcess.Name, true);
                                        TextBoxLogWriteLine(e);
                                        ErrorCreationKey = true;
                                    }
                                    if (!ErrorCreationKey)
                                    {
                                        TextBoxLogWriteLine("Created key {0} for asset '{1}'.", contentKey.Id, AssetToProcess.Name);
                                    }

                                }
                                formerkey = contentKey;
                                firstkeycreation = false;
                            }
                            else
                            {
                                contentKey = formerkey;
                                AssetToProcess.ContentKeys.Add(contentKey);
                                AssetToProcess.Update();
                                TextBoxLogWriteLine("Reusing key {0} for the asset {1} ", contentKey.Id, AssetToProcess.Name);
                            }
                        }
                    }
                    else if (form1.GetNumberOfAuthorizationPolicyOptions == 0)  // user wants to deliver with an external PlayReady server but the key exists already !
                    {
                        TextBoxLogWriteLine("Warning for asset '{0}'. A CENC key already exists. You need to make sure that your external PlayReady server can deliver the license for this asset.", AssetToProcess.Name, true);
                    }
                    else // let's use existing content key
                    {
                        contentKey = contentkeys.FirstOrDefault();
                        TextBoxLogWriteLine("Existing key '{0}' will be used for asset '{1}'.", contentKey.Id, AssetToProcess.Name);
                    }
                    if (form1.GetNumberOfAuthorizationPolicyOptions > 0) // PlayReady license and delivery from Azure Media Services
                    {
                        // let's create the Authorization Policy
                        IContentKeyAuthorizationPolicy contentKeyAuthorizationPolicy = _context.
                                       ContentKeyAuthorizationPolicies.
                                       CreateAsync("My Authorization Policy").Result;

                        // Associate the content key authorization policy with the content key.
                        contentKey.AuthorizationPolicyId = contentKeyAuthorizationPolicy.Id;
                        contentKey = contentKey.UpdateAsync().Result;

                        foreach (var form3 in form3list)
                        {
                            // let's build the PlayReady license template
                            string PlayReadyLicenseDeliveryConfig = null;
                            ErrorCreationKey = false;
                            try
                            {
                                PlayReadyLicenseDeliveryConfig = form4PlayReadyLicenseList[form3list.IndexOf(form3)].GetLicenseTemplate;
                                // PlayReadyLicenseDeliveryConfig = DynamicEncryption.ConfigurePlayReadyLicenseTemplate(form4PlayReadyLicenseList[form3list.IndexOf(form3)].GetLicenseTemplate);
                            }
                            catch (Exception e)
                            {
                                // Add useful information to the exception
                                TextBoxLogWriteLine("There is a problem when configuring the PlayReady license template.", true);
                                TextBoxLogWriteLine(e);
                                ErrorCreationKey = true;
                            }
                            if (!ErrorCreationKey)
                            {
                                IContentKeyAuthorizationPolicyOption policyOption = null;
                                try
                                {
                                    switch (form3.GetKeyRestrictionType)
                                    {
                                        case ContentKeyRestrictionType.Open:
                                            policyOption = DynamicEncryption.AddOpenAuthorizationPolicyOption(contentKey, ContentKeyDeliveryType.PlayReadyLicense, PlayReadyLicenseDeliveryConfig, _context);
                                            TextBoxLogWriteLine("Created Open authorization policy for the asset {0} ", contentKey.Id, AssetToProcess.Name);
                                            contentKeyAuthorizationPolicy.Options.Add(policyOption);
                                            break;

                                        case ContentKeyRestrictionType.TokenRestricted:
                                            TokenVerificationKey mytokenverifkey = null;
                                            string OpenIdDoc = null;
                                            switch (form3.GetDetailedTokenType)
                                            {
                                                case ExplorerTokenType.SWT:
                                                case ExplorerTokenType.JWTSym:
                                                    mytokenverifkey = new SymmetricVerificationKey(Convert.FromBase64String(form3.SymmetricKey));
                                                    break;

                                                case ExplorerTokenType.JWTOpenID:
                                                    OpenIdDoc = form3.GetOpenIdDiscoveryDocument;
                                                    break;

                                                case ExplorerTokenType.JWTX509:
                                                    mytokenverifkey = new X509CertTokenVerificationKey(form3.GetX509Certificate);
                                                    break;
                                            }

                                            policyOption = DynamicEncryption.AddTokenRestrictedAuthorizationPolicyPlayReady(contentKey, form3.GetAudience, form3.GetIssuer, form3.GetTokenRequiredClaims, form3.AddContentKeyIdentifierClaim, form3.GetTokenType, form3.GetDetailedTokenType, mytokenverifkey, _context, PlayReadyLicenseDeliveryConfig, OpenIdDoc);
                                            TextBoxLogWriteLine("Created Token CENC authorization policy for the asset {0} ", contentKey.Id, AssetToProcess.Name);
                                            contentKeyAuthorizationPolicy.Options.Add(policyOption);

                                            if (form3.GetDetailedTokenType != ExplorerTokenType.JWTOpenID) // not possible to create a test token if OpenId is used
                                            {
                                                // let display a test token
                                                X509SigningCredentials signingcred = null;
                                                if (form3.GetDetailedTokenType == ExplorerTokenType.JWTX509)
                                                {
                                                    signingcred = new X509SigningCredentials(form3.GetX509Certificate);
                                                }

                                                _context = Program.ConnectAndGetNewContext(_credentials); // otherwise cache issues with multiple options
                                                DynamicEncryption.TokenResult testToken = DynamicEncryption.GetTestToken(AssetToProcess, _context, form1.GetContentKeyType, signingcred, policyOption.Id);
                                                TextBoxLogWriteLine("The authorization test token for option #{0} ({1} with Bearer) is:\n{2}", form3list.IndexOf(form3), form3.GetTokenType.ToString(), Constants.Bearer + testToken.TokenString);
                                                System.Windows.Forms.Clipboard.SetText(Constants.Bearer + testToken.TokenString);
                                            }
                                            break;


                                        default:
                                            break;
                                    }
                                }
                                catch (Exception e)
                                {
                                    // Add useful information to the exception
                                    TextBoxLogWriteLine("There is a problem when creating the authorization policy for '{0}'.", AssetToProcess.Name, true);
                                    TextBoxLogWriteLine(e);
                                    ErrorCreationKey = true;
                                }
                            }
                        }
                        contentKeyAuthorizationPolicy.Update();
                    }

                    // Let's create the Asset Delivery Policy now
                    if (form1.GetDeliveryPolicyType != AssetDeliveryPolicyType.None)
                    {
                        IAssetDeliveryPolicy DelPol = null;
                        string name = string.Format("AssetDeliveryPolicy {0} ({1})", form1.GetContentKeyType.ToString(), form1.GetAssetDeliveryProtocol.ToString());
                        ErrorCreationKey = false;
                        try
                        {
                            if (form1.GetNumberOfAuthorizationPolicyOptions > 0) // Licenses delivered by Azure Media Services
                            {
                                DelPol = DynamicEncryption.CreateAssetDeliveryPolicyCENC(AssetToProcess, contentKey, form1.GetAssetDeliveryProtocol, name, _context, null, false, form2_PlayReady.PlayReadyCustomAttributes);
                            }
                            else // Licenses NOT delivered by Azure Media Services but by a third party server
                            {
                                DelPol = DynamicEncryption.CreateAssetDeliveryPolicyCENC(AssetToProcess, contentKey, form1.GetAssetDeliveryProtocol, name, _context, new Uri(form2_PlayReady.PlayReadyLAurl), form2_PlayReady.PlayReadyLAurlEncodeForSL, form2_PlayReady.PlayReadyCustomAttributes);
                            }

                            TextBoxLogWriteLine("Created asset delivery policy '{0}' for asset '{1}'.", DelPol.AssetDeliveryPolicyType, AssetToProcess.Name);
                        }
                        catch (Exception e)
                        {
                            TextBoxLogWriteLine("There is a problem when creating the delivery policy for '{0}'.", AssetToProcess.Name, true);
                            TextBoxLogWriteLine(e);
                            ErrorCreationKey = true;
                        }
                    }

                }
            }
        }