# Copyright 2018 RedHat Inc.
# All Rights Reserved.
#
#    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.

"""Tests the Multiple VMware Datastore backend store"""

import hashlib
from unittest import mock
import uuid

from oslo_config import cfg
from oslo_utils import secretutils
from oslo_utils import units
from oslo_vmware import api
from oslo_vmware import exceptions as vmware_exceptions
from oslo_vmware.objects import datacenter as oslo_datacenter
from oslo_vmware.objects import datastore as oslo_datastore
import six

import glance_store as store
import glance_store._drivers.vmware_datastore as vm_store
from glance_store import exceptions
from glance_store import location
from glance_store.tests import base
from glance_store.tests.unit import test_store_capabilities
from glance_store.tests import utils


FAKE_UUID = str(uuid.uuid4())

FIVE_KB = 5 * units.Ki

VMWARE_DS = {
    'debug': True,
    'vmware_server_host': '127.0.0.1',
    'vmware_server_username': 'username',
    'vmware_server_password': 'password',
    'vmware_store_image_dir': '/openstack_glance',
    'vmware_insecure': 'True',
    'vmware_datastores': ['a:b:0'],
}


def format_location(host_ip, folder_name, image_id, datastores):
    """
    Helper method that returns a VMware Datastore store URI given
    the component pieces.
    """
    scheme = 'vsphere'
    (datacenter_path, datastore_name, weight) = datastores[0].split(':')
    return ("%s://%s/folder%s/%s?dcPath=%s&dsName=%s"
            % (scheme, host_ip, folder_name,
               image_id, datacenter_path, datastore_name))


def fake_datastore_obj(*args, **kwargs):
    dc_obj = oslo_datacenter.Datacenter(ref='fake-ref',
                                        name='fake-name')
    dc_obj.path = args[0]
    return oslo_datastore.Datastore(ref='fake-ref',
                                    datacenter=dc_obj,
                                    name=args[1])


class TestMultiStore(base.MultiStoreBaseTest,
                     test_store_capabilities.TestStoreCapabilitiesChecking):

    # NOTE(flaper87): temporary until we
    # can move to a fully-local lib.
    # (Swift store's fault)
    _CONF = cfg.ConfigOpts()

    @mock.patch.object(vm_store.Store, '_get_datastore')
    @mock.patch('oslo_vmware.api.VMwareAPISession')
    def setUp(self, mock_api_session, mock_get_datastore):
        """Establish a clean test environment."""
        super(TestMultiStore, self).setUp()
        enabled_backends = {
            "vmware1": "vmware",
            "vmware2": "vmware"
        }
        self.hash_algo = 'sha256'
        self.conf = self._CONF
        self.conf(args=[])
        self.conf.register_opt(cfg.DictOpt('enabled_backends'))
        self.config(enabled_backends=enabled_backends)
        store.register_store_opts(self.conf)
        self.config(default_backend='vmware1', group='glance_store')

        # set vmware related config options
        self.config(group='vmware1',
                    vmware_server_username='admin',
                    vmware_server_password='admin',
                    vmware_server_host='127.0.0.1',
                    vmware_insecure='True',
                    vmware_datastores=['a:b:0'],
                    vmware_store_image_dir='/openstack_glance')

        self.config(group='vmware2',
                    vmware_server_username='admin',
                    vmware_server_password='admin',
                    vmware_server_host='127.0.0.1',
                    vmware_insecure='True',
                    vmware_datastores=['a:b:1'],
                    vmware_store_image_dir='/openstack_glance_1')
        # Ensure stores + locations cleared
        location.SCHEME_TO_CLS_BACKEND_MAP = {}
        store.create_multi_stores(self.conf)

        self.addCleanup(setattr, location, 'SCHEME_TO_CLS_BACKEND_MAP',
                        dict())
        self.addCleanup(self.conf.reset)

        vm_store.Store.CHUNKSIZE = 2

        mock_get_datastore.side_effect = fake_datastore_obj

        self.store = vm_store.Store(self.conf, backend="vmware1")
        self.store.configure()

    def _mock_http_connection(self):
        return mock.patch('six.moves.http_client.HTTPConnection')

    def test_location_url_prefix_is_set(self):
        expected_url_prefix = "vsphere://127.0.0.1/openstack_glance"
        self.assertEqual(expected_url_prefix, self.store.url_prefix)

    @mock.patch('oslo_vmware.api.VMwareAPISession')
    def test_get(self, mock_api_session):
        """Test a "normal" retrieval of an image in chunks."""
        expected_image_size = 31