# coding: utf-8

# -------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# --------------------------------------------------------------------------

# Current Operation Coverage:
#   ServerKeys: 4/4
#   ServerAzureADOnlyAuthentications: 0/4
#   EncryptionProtectors: 4/4
#   ManagedInstanceKeys: 4/4
#   ManagedInstanceEncryptionProtectors: 3/4

import unittest

import azure.mgmt.sql
from devtools_testutils import AzureMgmtTestCase, RandomNameResourceGroupPreparer

AZURE_LOCATION = "eastus"


class MgmtSqlTest(AzureMgmtTestCase):

    def setUp(self):
        super(MgmtSqlTest, self).setUp()
        self.mgmt_client = self.create_mgmt_client(azure.mgmt.sql.SqlManagementClient)

        if self.is_live:
            from azure.mgmt.keyvault import KeyVaultManagementClient

            self.keyvault_client = self.create_mgmt_client(KeyVaultManagementClient)

    def create_key(self, group_name, location, key_vault, tenant_id, object_id, object_id_2):
        if self.is_live:
            result = self.keyvault_client.vaults.begin_create_or_update(
                group_name,
                key_vault,
                {
                    "location": location,
                    "properties": {
                        "sku": {"family": "A", "name": "standard"},
                        "tenant_id": tenant_id,
                        "access_policies": [
                            {
                                "tenant_id": tenant_id,
                                "object_id": object_id,
                                "permissions": {
                                    "keys": [
                                        "get",
                                        "create",
                                        "delete",
                                        "list",
                                        "update",
                                        "import",
                                        "backup",
                                        "restore",
                                        "recover",
                                    ],
                                    "secrets": ["get", "list", "set", "delete", "backup", "restore", "recover"],
                                    "certificates": [
                                        "get",
                                        "list",
                                        "delete",
                                        "create",
                                        "import",
                                        "update",
                                        "managecontacts",
                                        "getissuers",
                                        "listissuers",
                                        "setissuers",
                                        "deleteissuers",
                                        "manageissuers",
                                        "recover",
                                    ],
                                    "storage": [
                                        "get",
                                        "list",
                                        "delete",
                                        "set",
                                        "update",
                                        "regeneratekey",
                                        "setsas",
                                        "listsas",
                                        "getsas",
                                        "deletesas",
                                    ],
                                },
                            },
                            {
                                "tenantId": tenant_id,
                                "objectId": object_id_2,
                                "permissions": {"keys": ["unwrapKey", "get", "wrapKey", "list"]},
                            },
                        ],
                        "enabled_for_disk_encryption": True,
                        "enable_soft_delete": True,
                        "soft_delete_retention_in_days": 90,
                        "nework_acls": {
                            "bypass": "AzureServices",
                            "default_action": "Allow",
                            "ip_rules": [],
                            "virtual_network_rules": [],
                        },
                    },
                },
            ).result()
            vault_url = result.properties.vault_uri
            vault_id = result.id

            from azure.keyvault.keys import KeyClient

            credentials = self.settings.get_azure_core_credentials()
            key_client = KeyClient(vault_url, credentials)

            # [START create_key]
            from dateutil import parser as date_parse

            expires_on = date_parse.parse("2050-02-02T08:00:00.000Z")

            key = key_client.create_key("testkey", "RSA", size=2048, expires_on=expires_on)
            return (vault_id, key.id)
        else:
            return ("000", "000")

    @unittest.skip("hard to test")
    def test_managed_instance_encryption_protector(self):

        RESOURCE_GROUP = "testManagedInstance"
        MANAGED_INSTANCE_NAME = "testinstancexxy"
        SUBSCRIPTION_ID = self.settings.SUBSCRIPTION_ID
        TENANT_ID = self.settings.TENANT_ID
        CLIENT_OID = self.settings.CLIENT_OID if self.is_live else "000"
        KEY_VAULT_NAME = self.get_resource_name("keyvaultxmmxh")
        ENCRYPTION_PROTECTOR_NAME = "current"

        # --------------------------------------------------------------------------
        # /ManagedInstances/get/Get managed instance[get]
        # --------------------------------------------------------------------------
        instance = self.mgmt_client.managed_instances.get(
            resource_group_name=RESOURCE_GROUP, managed_instance_name=MANAGED_INSTANCE_NAME
        )
        oid2 = instance.identity.principal_id

        VAULT_ID, KEY_URI = self.create_key(RESOURCE_GROUP, AZURE_LOCATION, KEY_VAULT_NAME, TENANT_ID, CLIENT_OID, oid2)

        # --------------------------------------------------------------------------
        # /ManagedInstanceKeys/put/Creates or updates a managed instance key[put]
        # --------------------------------------------------------------------------
        KEY_NAME = KEY_VAULT_NAME + "_testkey_" + KEY_URI.split("/")[-1]
        BODY = {"server_key_type": "AzureKeyVault", "uri": KEY_URI}
        result = self.mgmt_client.managed_instance_keys.begin_create_or_update(
            resource_group_name=RESOURCE_GROUP,
            managed_instance_name=MANAGED_INSTANCE_NAME,
            key_name=KEY_NAME,
            parameters=BODY,
        )
        result = result.result()

        # --------------------------------------------------------------------------
        # /ManagedInstanceEncryptionProtectors/put/Update the encryption protector to key vault[put]
        # --------------------------------------------------------------------------
        BODY = {"server_key_type": "AzureKeyVault", "server_key_name": KEY_NAME}
        result = self.mgmt_client.managed_instance_encryption_protectors.begin_create_or_update(
            resource_group_name=RESOURCE_GROUP,
            managed_instance_name=MANAGED_INSTANCE_NAME,
            encryption_protector_name=ENCRYPTION_PROTECTOR_NAME,
            parameters=BODY,
        )
        result = result.result()

        # --------------------------------------------------------------------------
        # /ManagedInstanceEncryptionProtectors/get/Get the encryption protector[get]
        # --------------------------------------------------------------------------
        result = self.mgmt_client.managed_instance_encryption_protectors.get(
            resource_group_name=RESOURCE_GROUP,
            managed_instance_name=MANAGED_INSTANCE_NAME,
            encryption_protector_name=ENCRYPTION_PROTECTOR_NAME,
        )

        # --------------------------------------------------------------------------
        # /ManagedInstanceEncryptionProtectors/get/List encryption protectors by managed instance[get]
        # --------------------------------------------------------------------------
        result = self.mgmt_client.managed_instance_encryption_protectors.list_by_instance(
            resource_group_name=RESOURCE_GROUP, managed_instance_name=MANAGED_INSTANCE_NAME
        )

    # --------------------------------------------------------------------------
    # /ManagedInstanceEncryptionProtectors/post/Revalidates the encryption protector[post]
    # --------------------------------------------------------------------------
    # result = self.mgmt_client.managed_instance_encryption_protectors.begin_revalidate(resource_group_name=RESOURCE_GROUP, managed_instance_name=MANAGED_INSTANCE_NAME, encryption_protector_name=ENCRYPTION_PROTECTOR_NAME)
    # result = result.result()

    # --------------------------------------------------------------------------
    # /ManagedInstanceKeys/delete/Delete the managed instance key[delete]
    # --------------------------------------------------------------------------
    # result = self.mgmt_client.managed_instance_keys.begin_delete(resource_group_name=RESOURCE_GROUP, managed_instance_name=MANAGED_INSTANCE_NAME, key_name=KEY_NAME)
    # result = result.result()

    @unittest.skip("hard to test")
    @RandomNameResourceGroupPreparer(location=AZURE_LOCATION)
    def test_encryption_protector(self, resource_group):

        SUBSCRIPTION_ID = self.settings.SUBSCRIPTION_ID
        TENANT_ID = self.settings.TENANT_ID
        CLIENT_OID = self.settings.CLIENT_OID if self.is_live else "000"
        RESOURCE_GROUP = resource_group.name
        SERVER_NAME = "myserverxpczk"
        KEY_VAULT_NAME = self.get_resource_name("keyvaultxmmxkk")
        ENCRYPTION_PROTECTOR_NAME = "current"

        # --------------------------------------------------------------------------
        # /Servers/put/Create server[put]
        # --------------------------------------------------------------------------
        BODY = {
            "location": AZURE_LOCATION,
            "identity": {"type": "SystemAssigned"},
            "administrator_login": "dummylogin",
            "administrator_login_password": "Un53cuRE!",
            "version": "12.0",
            "public_network_access": "Enabled",
        }
        result = self.mgmt_client.servers.begin_create_or_update(
            resource_group_name=RESOURCE_GROUP, server_name=SERVER_NAME, parameters=BODY
        )
        server = result.result()
        oid2 = server.identity.principal_id

        VAULT_ID, KEY_URI = self.create_key(RESOURCE_GROUP, AZURE_LOCATION, KEY_VAULT_NAME, TENANT_ID, CLIENT_OID, oid2)

        # --------------------------------------------------------------------------
        # /ServerKeys/put/Creates or updates a server key[put]
        # --------------------------------------------------------------------------
        KEY_NAME = KEY_VAULT_NAME + "_testkey_" + KEY_URI.split("/")[-1]
        BODY = {"server_key_type": "AzureKeyVault", "uri": KEY_URI}
        result = self.mgmt_client.server_keys.begin_create_or_update(
            resource_group_name=RESOURCE_GROUP, server_name=SERVER_NAME, key_name=KEY_NAME, parameters=BODY
        )
        result = result.result()

        # --------------------------------------------------------------------------
        # /EncryptionProtectors/put/Update the encryption protector to service managed[put]
        # --------------------------------------------------------------------------
        BODY = {"server_key_type": "AzureKeyVault", "server_key_name": KEY_NAME}
        result = self.mgmt_client.encryption_protectors.begin_create_or_update(
            resource_group_name=RESOURCE_GROUP,
            server_name=SERVER_NAME,
            encryption_protector_name=ENCRYPTION_PROTECTOR_NAME,
            parameters=BODY,
        )
        result = result.result()

        # --------------------------------------------------------------------------
        # /EncryptionProtectors/get/Get the encryption protector[get]
        # --------------------------------------------------------------------------
        result = self.mgmt_client.encryption_protectors.get(
            resource_group_name=RESOURCE_GROUP,
            server_name=SERVER_NAME,
            encryption_protector_name=ENCRYPTION_PROTECTOR_NAME,
        )

        # --------------------------------------------------------------------------
        # /EncryptionProtectors/get/List encryption protectors by server[get]
        # --------------------------------------------------------------------------
        result = self.mgmt_client.encryption_protectors.list_by_server(
            resource_group_name=RESOURCE_GROUP, server_name=SERVER_NAME
        )

        # --------------------------------------------------------------------------
        # /EncryptionProtectors/post/Revalidates the encryption protector[post]
        # --------------------------------------------------------------------------
        result = self.mgmt_client.encryption_protectors.begin_revalidate(
            resource_group_name=RESOURCE_GROUP,
            server_name=SERVER_NAME,
            encryption_protector_name=ENCRYPTION_PROTECTOR_NAME,
        )
        result = result.result()

        # --------------------------------------------------------------------------
        # /Servers/delete/Delete server[delete]
        # --------------------------------------------------------------------------
        result = self.mgmt_client.servers.begin_delete(resource_group_name=RESOURCE_GROUP, server_name=SERVER_NAME)
        result = result.result()

    @unittest.skip("hard to test")
    def test_instance_key(self):

        RESOURCE_GROUP = "testManagedInstance"
        MANAGED_INSTANCE_NAME = "testinstancexxy"
        SUBSCRIPTION_ID = self.settings.SUBSCRIPTION_ID
        TENANT_ID = self.settings.TENANT_ID
        CLIENT_OID = self.settings.CLIENT_OID if self.is_live else "000"
        KEY_VAULT_NAME = self.get_resource_name("keyvaultxmmxh")

        # --------------------------------------------------------------------------
        # /ManagedInstances/get/Get managed instance[get]
        # --------------------------------------------------------------------------
        instance = self.mgmt_client.managed_instances.get(
            resource_group_name=RESOURCE_GROUP, managed_instance_name=MANAGED_INSTANCE_NAME
        )
        oid2 = instance.identity.principal_id

        VAULT_ID, KEY_URI = self.create_key(RESOURCE_GROUP, AZURE_LOCATION, KEY_VAULT_NAME, TENANT_ID, CLIENT_OID, oid2)

        # --------------------------------------------------------------------------
        # /ManagedInstanceKeys/put/Creates or updates a managed instance key[put]
        # --------------------------------------------------------------------------
        KEY_NAME = KEY_VAULT_NAME + "_testkey_" + KEY_URI.split("/")[-1]
        BODY = {"server_key_type": "AzureKeyVault", "uri": KEY_URI}
        result = self.mgmt_client.managed_instance_keys.begin_create_or_update(
            resource_group_name=RESOURCE_GROUP,
            managed_instance_name=MANAGED_INSTANCE_NAME,
            key_name=KEY_NAME,
            parameters=BODY,
        )
        result = result.result()

        # --------------------------------------------------------------------------
        # /ManagedInstanceKeys/get/Get the managed instance key[get]
        # --------------------------------------------------------------------------
        result = self.mgmt_client.managed_instance_keys.get(
            resource_group_name=RESOURCE_GROUP, managed_instance_name=MANAGED_INSTANCE_NAME, key_name=KEY_NAME
        )

        # --------------------------------------------------------------------------
        # /ManagedInstanceKeys/get/List the keys for a managed instance.[get]
        # --------------------------------------------------------------------------
        result = self.mgmt_client.managed_instance_keys.list_by_instance(
            resource_group_name=RESOURCE_GROUP, managed_instance_name=MANAGED_INSTANCE_NAME
        )

        # --------------------------------------------------------------------------
        # /ManagedInstanceKeys/delete/Delete the managed instance key[delete]
        # --------------------------------------------------------------------------
        result = self.mgmt_client.managed_instance_keys.begin_delete(
            resource_group_name=RESOURCE_GROUP, managed_instance_name=MANAGED_INSTANCE_NAME, key_name=KEY_NAME
        )
        result = result.result()

    @unittest.skip("hard to test")
    @RandomNameResourceGroupPreparer(location=AZURE_LOCATION)
    def test_server_key(self, resource_group):

        SUBSCRIPTION_ID = self.settings.SUBSCRIPTION_ID
        TENANT_ID = self.settings.TENANT_ID
        CLIENT_OID = self.settings.CLIENT_OID if self.is_live else "000"
        RESOURCE_GROUP = resource_group.name
        SERVER_NAME = "myserverxpczk"
        KEY_VAULT_NAME = self.get_resource_name("keyvaultxmmxhh")
        # KEY_NAME = "mykeyzz"

        # --------------------------------------------------------------------------
        # /Servers/put/Create server[put]
        # --------------------------------------------------------------------------
        BODY = {
            "location": AZURE_LOCATION,
            "identity": {"type": "SystemAssigned"},
            "administrator_login": "dummylogin",
            "administrator_login_password": "Un53cuRE!",
            "version": "12.0",
            "public_network_access": "Enabled",
        }
        result = self.mgmt_client.servers.begin_create_or_update(
            resource_group_name=RESOURCE_GROUP, server_name=SERVER_NAME, parameters=BODY
        )
        server = result.result()
        oid2 = server.identity.principal_id

        VAULT_ID, KEY_URI = self.create_key(RESOURCE_GROUP, AZURE_LOCATION, KEY_VAULT_NAME, TENANT_ID, CLIENT_OID, oid2)

        # --------------------------------------------------------------------------
        # /ServerKeys/put/Creates or updates a server key[put]
        # --------------------------------------------------------------------------
        KEY_NAME = KEY_VAULT_NAME + "_testkey_" + KEY_URI.split("/")[-1]
        BODY = {
            "server_key_type": "AzureKeyVault",
            #   "uri": "https://someVault.vault.azure.net/keys/someKey/01234567890123456789012345678901"
            "uri": KEY_URI,
        }
        result = self.mgmt_client.server_keys.begin_create_or_update(
            resource_group_name=RESOURCE_GROUP, server_name=SERVER_NAME, key_name=KEY_NAME, parameters=BODY
        )
        result = result.result()

        # --------------------------------------------------------------------------
        # /ServerKeys/get/Get the server key[get]
        # --------------------------------------------------------------------------
        result = self.mgmt_client.server_keys.get(
            resource_group_name=RESOURCE_GROUP, server_name=SERVER_NAME, key_name=KEY_NAME
        )

        # --------------------------------------------------------------------------
        # /ServerKeys/get/List the server keys by server[get]
        # --------------------------------------------------------------------------
        result = self.mgmt_client.server_keys.list_by_server(
            resource_group_name=RESOURCE_GROUP, server_name=SERVER_NAME
        )

        # --------------------------------------------------------------------------
        # /ServerKeys/delete/Delete the server key[delete]
        # --------------------------------------------------------------------------
        result = self.mgmt_client.server_keys.begin_delete(
            resource_group_name=RESOURCE_GROUP, server_name=SERVER_NAME, key_name=KEY_NAME
        )
        result = result.result()

        # --------------------------------------------------------------------------
        # /Servers/delete/Delete server[delete]
        # --------------------------------------------------------------------------
        result = self.mgmt_client.servers.begin_delete(resource_group_name=RESOURCE_GROUP, server_name=SERVER_NAME)
        result = result.result()

    @unittest.skip("unavailable")
    @RandomNameResourceGroupPreparer(location=AZURE_LOCATION)
    def test_server_azure_adonly_authentication(self, resource_group):

        RESOURCE_GROUP = resource_group.name
        SERVER_NAME = "myserverxpxy"
        AUTHENTICATION_NAME = "myauthentication"

        # --------------------------------------------------------------------------
        # /Servers/put/Create server[put]
        # --------------------------------------------------------------------------
        BODY = {
            "location": AZURE_LOCATION,
            "administrator_login": "dummylogin",
            "administrator_login_password": "Un53cuRE!",
        }
        result = self.mgmt_client.servers.begin_create_or_update(
            resource_group_name=RESOURCE_GROUP, server_name=SERVER_NAME, parameters=BODY
        )
        result = result.result()

        # --------------------------------------------------------------------------
        # /ServerAzureADOnlyAuthentications/put/Creates or updates Azure Active Directory only authentication object.[put]
        # --------------------------------------------------------------------------
        BODY = {"azure_ad_only_authentication": False}
        result = self.mgmt_client.server_azure_ad_only_authentications.begin_create_or_update(
            resource_group_name=RESOURCE_GROUP,
            server_name=SERVER_NAME,
            authentication_name=AUTHENTICATION_NAME,
            parameters=BODY,
        )
        result = result.result()

        # --------------------------------------------------------------------------
        # /ServerAzureADOnlyAuthentications/get/Gets a Azure Active Directory only authentication property.[get]
        # --------------------------------------------------------------------------
        result = self.mgmt_client.server_azure_ad_only_authentications.get(
            resource_group_name=RESOURCE_GROUP, server_name=SERVER_NAME, authentication_name=AUTHENTICATION_NAME
        )

        # --------------------------------------------------------------------------
        # /ServerAzureADOnlyAuthentications/get/Gets a list of Azure Active Directory only authentication object.[get]
        # --------------------------------------------------------------------------
        result = self.mgmt_client.server_azure_ad_only_authentications.list_by_server(
            resource_group_name=RESOURCE_GROUP, server_name=SERVER_NAME
        )

        # --------------------------------------------------------------------------
        # /ServerAzureADOnlyAuthentications/delete/Deletes Azure Active Directory only authentication object.[delete]
        # --------------------------------------------------------------------------
        result = self.mgmt_client.server_azure_ad_only_authentications.begin_delete(
            resource_group_name=RESOURCE_GROUP, server_name=SERVER_NAME, authentication_name=AUTHENTICATION_NAME
        )
        result = result.result()

        # --------------------------------------------------------------------------
        # /Servers/delete/Delete server[delete]
        # --------------------------------------------------------------------------
        result = self.mgmt_client.servers.begin_delete(resource_group_name=RESOURCE_GROUP, server_name=SERVER_NAME)
        result = result.result()
