# Copyright 2020 Curtin University
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Author: James Diprose


import os
import unittest
import uuid

from azure.storage.blob import ContainerClient, BlobClient

from mag_archiver.azure import list_containers, copy_container, list_blobs, create_container, delete_container, \
    create_blob, delete_table, create_table


def generate_names(num_names, prefix):
    # Create containers
    names = []
    for i in range(num_names):
        name = make_unique_name(prefix)
        names.append(name)
    return names


def make_unique_name(prefix: str):
    return f"{prefix}-{str(uuid.uuid4())}"


class TestAzure(unittest.TestCase):
    account_name: str
    account_key: str

    def __init__(self, *args, **kwargs):
        super(TestAzure, self).__init__(*args, **kwargs)
        self.account_name = os.getenv('TEST_AZURE_STORAGE_ACCOUNT_NAME')
        self.account_key = os.getenv('TEST_AZURE_STORAGE_ACCOUNT_KEY')

    def test_create_table(self):
        table_name = 'TestCreateTable'
        try:
            # Create a table
            result = create_table(self.account_name, self.account_key, table_name)
            self.assertTrue(result)
        finally:
            # Cleanup
            delete_table(self.account_name, self.account_key, table_name)

    def test_delete_table(self):
        table_name = 'TestDeleteTable'
        try:
            # Create a table
            create_table(self.account_name, self.account_key, table_name)

            # Delete table
            result = delete_table(self.account_name, self.account_key, table_name)
            self.assertTrue(result)
        finally:
            # Cleanup
            delete_table(self.account_name, self.account_key, table_name)

    def test_create_container(self):
        container_name = make_unique_name('test-create-container')
        try:
            # Create a container
            result: ContainerClient = create_container(self.account_name, self.account_key, container_name)
            self.assertIsInstance(result, ContainerClient)
            self.assertEqual(result.container_name, container_name)
        finally:
            # Cleanup
            delete_container(self.account_name, self.account_key, container_name)

    def test_create_blob(self):
        container_name = make_unique_name('test-create-blob')
        try:
            # Create a container for the blob
            create_container(self.account_name, self.account_key, container_name)

            # Create a blob
            blob_name = make_unique_name('test-create-blob') + '.txt'
            blob_data = 'Hello world!'
            result: BlobClient = create_blob(self.account_name, self.account_key, container_name, blob_name, blob_data)
            self.assertIsInstance(result, BlobClient)
            self.assertEqual(result.blob_name, blob_name)
        finally:
            # Cleanup
            delete_container(self.account_name, self.account_key, container_name)

    def test_list_containers(self):
        num_containers = 3
        names = generate_names(num_containers, 'test-list-containers')
        try:
            # Create containers
            for name in names:
                create_container(self.account_name, self.account_key, name)

            # List containers
            containers = list_containers(self.account_name, self.account_key)
            self.assertEqual(len(containers), num_containers + 1)
        finally:
            # Cleanup
            for name in names:
                delete_container(self.account_name, self.account_key, name)

    def test_delete_container(self):
        container_name = make_unique_name('test-delete-container')
        try:
            create_container(self.account_name, self.account_key, container_name)
            delete_container(self.account_name, self.account_key, container_name)
            containers = list_containers(self.account_name, self.account_key)
            container_names = [c.name for c in containers]
            self.assertNotIn(container_name, container_names)
        finally:
            # Cleanup
            delete_container(self.account_name, self.account_key, container_name)

    def test_list_blobs(self):
        container_name = make_unique_name('test-list-blobs')

        try:
            # Create container to store the blobs
            create_container(self.account_name, self.account_key, container_name)

            # Create the blobs
            num_blobs = 3
            blob_data = 'Hello world!'
            names = generate_names(num_blobs, 'test-list-blobs')
            for name in names:
                file_name = f'{name}.txt'
                create_blob(self.account_name, self.account_key, container_name, file_name, blob_data)

            # Check that we can find the blobs
            blobs = list_blobs(self.account_name, self.account_key, container_name)
            self.assertEqual(len(blobs), num_blobs)
        finally:
            # Cleanup
            delete_container(self.account_name, self.account_key, container_name)

    def test_copy_container(self):
        source_container = make_unique_name('test-copy-container-source')
        target_container = make_unique_name('test-copy-container-target')
        target_folder = 'target-folder'

        try:
            # Create containers and blobs
            create_container(self.account_name, self.account_key, source_container)
            create_container(self.account_name, self.account_key, target_container)

            # Create blobs in source container
            num_blobs = 3
            blob_data = 'Hello world!'
            names = generate_names(num_blobs, 'test-copy-container')
            for name in names:
                file_name = f'{name}.txt'
                create_blob(self.account_name, self.account_key, source_container, file_name, blob_data)

            # Copy blobs from one container to another
            copy_container(self.account_name, self.account_key, source_container, target_container, target_folder)

            # Check results
            blobs = list_blobs(self.account_name, self.account_key, target_container)
            self.assertEqual(len(blobs), num_blobs)
        finally:
            # Delete container
            delete_container(self.account_name, self.account_key, source_container)
            delete_container(self.account_name, self.account_key, target_container)

[((47, 28, 47, 72), 'os.getenv', 'os.getenv', ({(47, 38, 47, 71): '"""TEST_AZURE_STORAGE_ACCOUNT_NAME"""'}, {}), "('TEST_AZURE_STORAGE_ACCOUNT_NAME')", False, 'import os\n'), ((48, 27, 48, 70), 'os.getenv', 'os.getenv', ({(48, 37, 48, 69): '"""TEST_AZURE_STORAGE_ACCOUNT_KEY"""'}, {}), "('TEST_AZURE_STORAGE_ACCOUNT_KEY')", False, 'import os\n'), ((54, 21, 54, 82), 'mag_archiver.azure.create_table', 'create_table', ({(54, 34, 54, 51): 'self.account_name', (54, 53, 54, 69): 'self.account_key', (54, 71, 54, 81): 'table_name'}, {}), '(self.account_name, self.account_key, table_name)', False, 'from mag_archiver.azure import list_containers, copy_container, list_blobs, create_container, delete_container, create_blob, delete_table, create_table\n'), ((58, 12, 58, 73), 'mag_archiver.azure.delete_table', 'delete_table', ({(58, 25, 58, 42): 'self.account_name', (58, 44, 58, 60): 'self.account_key', (58, 62, 58, 72): 'table_name'}, {}), '(self.account_name, self.account_key, table_name)', False, 'from mag_archiver.azure import list_containers, copy_container, list_blobs, create_container, delete_container, create_blob, delete_table, create_table\n'), ((64, 12, 64, 73), 'mag_archiver.azure.create_table', 'create_table', ({(64, 25, 64, 42): 'self.account_name', (64, 44, 64, 60): 'self.account_key', (64, 62, 64, 72): 'table_name'}, {}), '(self.account_name, self.account_key, table_name)', False, 'from mag_archiver.azure import list_containers, copy_container, list_blobs, create_container, delete_container, create_blob, delete_table, create_table\n'), ((67, 21, 67, 82), 'mag_archiver.azure.delete_table', 'delete_table', ({(67, 34, 67, 51): 'self.account_name', (67, 53, 67, 69): 'self.account_key', (67, 71, 67, 81): 'table_name'}, {}), '(self.account_name, self.account_key, table_name)', False, 'from mag_archiver.azure import list_containers, copy_container, list_blobs, create_container, delete_container, create_blob, delete_table, create_table\n'), ((71, 12, 71, 73), 'mag_archiver.azure.delete_table', 'delete_table', ({(71, 25, 71, 42): 'self.account_name', (71, 44, 71, 60): 'self.account_key', (71, 62, 71, 72): 'table_name'}, {}), '(self.account_name, self.account_key, table_name)', False, 'from mag_archiver.azure import list_containers, copy_container, list_blobs, create_container, delete_container, create_blob, delete_table, create_table\n'), ((77, 38, 77, 107), 'mag_archiver.azure.create_container', 'create_container', ({(77, 55, 77, 72): 'self.account_name', (77, 74, 77, 90): 'self.account_key', (77, 92, 77, 106): 'container_name'}, {}), '(self.account_name, self.account_key, container_name)', False, 'from mag_archiver.azure import list_containers, copy_container, list_blobs, create_container, delete_container, create_blob, delete_table, create_table\n'), ((82, 12, 82, 81), 'mag_archiver.azure.delete_container', 'delete_container', ({(82, 29, 82, 46): 'self.account_name', (82, 48, 82, 64): 'self.account_key', (82, 66, 82, 80): 'container_name'}, {}), '(self.account_name, self.account_key, container_name)', False, 'from mag_archiver.azure import list_containers, copy_container, list_blobs, create_container, delete_container, create_blob, delete_table, create_table\n'), ((88, 12, 88, 81), 'mag_archiver.azure.create_container', 'create_container', ({(88, 29, 88, 46): 'self.account_name', (88, 48, 88, 64): 'self.account_key', (88, 66, 88, 80): 'container_name'}, {}), '(self.account_name, self.account_key, container_name)', False, 'from mag_archiver.azure import list_containers, copy_container, list_blobs, create_container, delete_container, create_blob, delete_table, create_table\n'), ((93, 33, 93, 119), 'mag_archiver.azure.create_blob', 'create_blob', ({(93, 45, 93, 62): 'self.account_name', (93, 64, 93, 80): 'self.account_key', (93, 82, 93, 96): 'container_name', (93, 98, 93, 107): 'blob_name', (93, 109, 93, 118): 'blob_data'}, {}), '(self.account_name, self.account_key, container_name, blob_name,\n    blob_data)', False, 'from mag_archiver.azure import list_containers, copy_container, list_blobs, create_container, delete_container, create_blob, delete_table, create_table\n'), ((98, 12, 98, 81), 'mag_archiver.azure.delete_container', 'delete_container', ({(98, 29, 98, 46): 'self.account_name', (98, 48, 98, 64): 'self.account_key', (98, 66, 98, 80): 'container_name'}, {}), '(self.account_name, self.account_key, container_name)', False, 'from mag_archiver.azure import list_containers, copy_container, list_blobs, create_container, delete_container, create_blob, delete_table, create_table\n'), ((109, 25, 109, 77), 'mag_archiver.azure.list_containers', 'list_containers', ({(109, 41, 109, 58): 'self.account_name', (109, 60, 109, 76): 'self.account_key'}, {}), '(self.account_name, self.account_key)', False, 'from mag_archiver.azure import list_containers, copy_container, list_blobs, create_container, delete_container, create_blob, delete_table, create_table\n'), ((119, 12, 119, 81), 'mag_archiver.azure.create_container', 'create_container', ({(119, 29, 119, 46): 'self.account_name', (119, 48, 119, 64): 'self.account_key', (119, 66, 119, 80): 'container_name'}, {}), '(self.account_name, self.account_key, container_name)', False, 'from mag_archiver.azure import list_containers, copy_container, list_blobs, create_container, delete_container, create_blob, delete_table, create_table\n'), ((120, 12, 120, 81), 'mag_archiver.azure.delete_container', 'delete_container', ({(120, 29, 120, 46): 'self.account_name', (120, 48, 120, 64): 'self.account_key', (120, 66, 120, 80): 'container_name'}, {}), '(self.account_name, self.account_key, container_name)', False, 'from mag_archiver.azure import list_containers, copy_container, list_blobs, create_container, delete_container, create_blob, delete_table, create_table\n'), ((121, 25, 121, 77), 'mag_archiver.azure.list_containers', 'list_containers', ({(121, 41, 121, 58): 'self.account_name', (121, 60, 121, 76): 'self.account_key'}, {}), '(self.account_name, self.account_key)', False, 'from mag_archiver.azure import list_containers, copy_container, list_blobs, create_container, delete_container, create_blob, delete_table, create_table\n'), ((126, 12, 126, 81), 'mag_archiver.azure.delete_container', 'delete_container', ({(126, 29, 126, 46): 'self.account_name', (126, 48, 126, 64): 'self.account_key', (126, 66, 126, 80): 'container_name'}, {}), '(self.account_name, self.account_key, container_name)', False, 'from mag_archiver.azure import list_containers, copy_container, list_blobs, create_container, delete_container, create_blob, delete_table, create_table\n'), ((133, 12, 133, 81), 'mag_archiver.azure.create_container', 'create_container', ({(133, 29, 133, 46): 'self.account_name', (133, 48, 133, 64): 'self.account_key', (133, 66, 133, 80): 'container_name'}, {}), '(self.account_name, self.account_key, container_name)', False, 'from mag_archiver.azure import list_containers, copy_container, list_blobs, create_container, delete_container, create_blob, delete_table, create_table\n'), ((144, 20, 144, 83), 'mag_archiver.azure.list_blobs', 'list_blobs', ({(144, 31, 144, 48): 'self.account_name', (144, 50, 144, 66): 'self.account_key', (144, 68, 144, 82): 'container_name'}, {}), '(self.account_name, self.account_key, container_name)', False, 'from mag_archiver.azure import list_containers, copy_container, list_blobs, create_container, delete_container, create_blob, delete_table, create_table\n'), ((148, 12, 148, 81), 'mag_archiver.azure.delete_container', 'delete_container', ({(148, 29, 148, 46): 'self.account_name', (148, 48, 148, 64): 'self.account_key', (148, 66, 148, 80): 'container_name'}, {}), '(self.account_name, self.account_key, container_name)', False, 'from mag_archiver.azure import list_containers, copy_container, list_blobs, create_container, delete_container, create_blob, delete_table, create_table\n'), ((157, 12, 157, 83), 'mag_archiver.azure.create_container', 'create_container', ({(157, 29, 157, 46): 'self.account_name', (157, 48, 157, 64): 'self.account_key', (157, 66, 157, 82): 'source_container'}, {}), '(self.account_name, self.account_key, source_container)', False, 'from mag_archiver.azure import list_containers, copy_container, list_blobs, create_container, delete_container, create_blob, delete_table, create_table\n'), ((158, 12, 158, 83), 'mag_archiver.azure.create_container', 'create_container', ({(158, 29, 158, 46): 'self.account_name', (158, 48, 158, 64): 'self.account_key', (158, 66, 158, 82): 'target_container'}, {}), '(self.account_name, self.account_key, target_container)', False, 'from mag_archiver.azure import list_containers, copy_container, list_blobs, create_container, delete_container, create_blob, delete_table, create_table\n'), ((169, 12, 169, 114), 'mag_archiver.azure.copy_container', 'copy_container', ({(169, 27, 169, 44): 'self.account_name', (169, 46, 169, 62): 'self.account_key', (169, 64, 169, 80): 'source_container', (169, 82, 169, 98): 'target_container', (169, 100, 169, 113): 'target_folder'}, {}), '(self.account_name, self.account_key, source_container,\n    target_container, target_folder)', False, 'from mag_archiver.azure import list_containers, copy_container, list_blobs, create_container, delete_container, create_blob, delete_table, create_table\n'), ((172, 20, 172, 85), 'mag_archiver.azure.list_blobs', 'list_blobs', ({(172, 31, 172, 48): 'self.account_name', (172, 50, 172, 66): 'self.account_key', (172, 68, 172, 84): 'target_container'}, {}), '(self.account_name, self.account_key, target_container)', False, 'from mag_archiver.azure import list_containers, copy_container, list_blobs, create_container, delete_container, create_blob, delete_table, create_table\n'), ((176, 12, 176, 83), 'mag_archiver.azure.delete_container', 'delete_container', ({(176, 29, 176, 46): 'self.account_name', (176, 48, 176, 64): 'self.account_key', (176, 66, 176, 82): 'source_container'}, {}), '(self.account_name, self.account_key, source_container)', False, 'from mag_archiver.azure import list_containers, copy_container, list_blobs, create_container, delete_container, create_blob, delete_table, create_table\n'), ((177, 12, 177, 83), 'mag_archiver.azure.delete_container', 'delete_container', ({(177, 29, 177, 46): 'self.account_name', (177, 48, 177, 64): 'self.account_key', (177, 66, 177, 82): 'target_container'}, {}), '(self.account_name, self.account_key, target_container)', False, 'from mag_archiver.azure import list_containers, copy_container, list_blobs, create_container, delete_container, create_blob, delete_table, create_table\n'), ((38, 27, 38, 39), 'uuid.uuid4', 'uuid.uuid4', ({}, {}), '()', False, 'import uuid\n'), ((106, 16, 106, 75), 'mag_archiver.azure.create_container', 'create_container', ({(106, 33, 106, 50): 'self.account_name', (106, 52, 106, 68): 'self.account_key', (106, 70, 106, 74): 'name'}, {}), '(self.account_name, self.account_key, name)', False, 'from mag_archiver.azure import list_containers, copy_container, list_blobs, create_container, delete_container, create_blob, delete_table, create_table\n'), ((114, 16, 114, 75), 'mag_archiver.azure.delete_container', 'delete_container', ({(114, 33, 114, 50): 'self.account_name', (114, 52, 114, 68): 'self.account_key', (114, 70, 114, 74): 'name'}, {}), '(self.account_name, self.account_key, name)', False, 'from mag_archiver.azure import list_containers, copy_container, list_blobs, create_container, delete_container, create_blob, delete_table, create_table\n'), ((141, 16, 141, 102), 'mag_archiver.azure.create_blob', 'create_blob', ({(141, 28, 141, 45): 'self.account_name', (141, 47, 141, 63): 'self.account_key', (141, 65, 141, 79): 'container_name', (141, 81, 141, 90): 'file_name', (141, 92, 141, 101): 'blob_data'}, {}), '(self.account_name, self.account_key, container_name, file_name,\n    blob_data)', False, 'from mag_archiver.azure import list_containers, copy_container, list_blobs, create_container, delete_container, create_blob, delete_table, create_table\n'), ((166, 16, 166, 104), 'mag_archiver.azure.create_blob', 'create_blob', ({(166, 28, 166, 45): 'self.account_name', (166, 47, 166, 63): 'self.account_key', (166, 65, 166, 81): 'source_container', (166, 83, 166, 92): 'file_name', (166, 94, 166, 103): 'blob_data'}, {}), '(self.account_name, self.account_key, source_container,\n    file_name, blob_data)', False, 'from mag_archiver.azure import list_containers, copy_container, list_blobs, create_container, delete_container, create_blob, delete_table, create_table\n')]