# Copyright 2012 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
# Copyright 2012 Nebula, Inc.
#
#    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.

import tempfile

from django.conf import settings
from django.core.files.uploadedfile import InMemoryUploadedFile
from django.test.utils import override_settings
from django.urls import reverse

import mock
import six

from horizon import tables as horizon_tables
from openstack_dashboard import api
from openstack_dashboard.test import helpers as test

from openstack_dashboard.dashboards.project.images.images import forms
from openstack_dashboard.dashboards.project.images.images import tables


IMAGES_INDEX_URL = reverse('horizon:project:images:index')


class CreateImageFormTests(test.ResetImageAPIVersionMixin, test.TestCase):
    @mock.patch.object(api.glance, 'image_list_detailed')
    def test_no_location_or_file(self, mock_image_list):
        mock_image_list.side_effect = [
            [self.images.list(), False, False],
            [self.images.list(), False, False]
        ]

        image_calls = [
            mock.call(test.IsA(dict), filters={'disk_format': 'aki'}),
            mock.call(test.IsA(dict), filters={'disk_format': 'ari'})
        ]

        post = {
            'name': u'Ubuntu 11.10',
            'source_type': u'file',
            'description': u'Login with admin/admin',
            'disk_format': u'qcow2',
            'architecture': u'x86-64',
            'min_disk': 15,
            'min_ram': 512,
            'is_public': 1}
        files = {}
        form = forms.CreateImageForm(post, files)

        self.assertFalse(form.is_valid())
        mock_image_list.assert_has_calls(image_calls)


class UpdateImageFormTests(test.ResetImageAPIVersionMixin, test.TestCase):
    def test_is_format_field_editable(self):
        form = forms.UpdateImageForm({})
        disk_format = form.fields['disk_format']
        self.assertFalse(disk_format.widget.attrs.get('readonly', False))

    @mock.patch.object(api.glance, 'image_get')
    def test_image_update(self, mock_image_get):
        image = self.images.first()
        mock_image_get.return_value = image

        url = reverse('horizon:project:images:images:update',
                      args=[image.id])
        res = self.client.get(url)

        self.assertNoFormErrors(res)
        self.assertEqual(res.context['image'].disk_format,
                         image.disk_format)
        mock_image_get.assert_called_once_with(test.IsHttpRequest(),
                                               image.id)

    @override_settings(OPENSTACK_API_VERSIONS={'image': 1})
    @mock.patch.object(api.glance, 'image_get')
    @mock.patch.object(api.glance, 'image_update')
    def test_image_update_post_v1(self, mock_image_update, mock_image_get):
        image = self.images.first()
        data = {
            'name': u'Ubuntu 11.10',
            'image_id': str(image.id),
            'description': u'Login with admin/admin',
            'source_type': u'url',
            'image_url': u'http://cloud-images.ubuntu.com/releases/'
                         u'oneiric/release/ubuntu-11.10-server-cloudimg'
                         u'-amd64-disk1.img',
            'disk_format': u'qcow2',
            'architecture': u'x86-64',
            'min_disk': 15,
            'min_ram': 512,
            'is_public': False,
            'protected': False,
            'method': 'UpdateImageForm'}

        mock_image_get.return_value = image
        mock_image_update.return_value = image

        url = reverse('horizon:project:images:images:update',
                      args=[image.id])
        res = self.client.post(url, data)

        self.assertNoFormErrors(res)
        self.assertEqual(res.status_code, 302)
        mock_image_get.assert_called_once_with(test.IsHttpRequest(),
                                               str(image.id))
        mock_image_update.assert_called_once_with(
            test.IsHttpRequest(),
            image.id,
            is_public=data['is_public'],
            protected=data['protected'],
            disk_format=data['disk_format'],
            container_format="bare",
            name=data['name'],
            min_ram=data['min_ram'],
            min_disk=data['min_disk'],
            properties={
                'description': data['description'],
                'architecture': data['architecture']})

    @mock.patch.object(api.glance, 'image_get')
    @mock.patch.object(api.glance, 'image_update')
    def test_image_update_post_v2(self, mock_image_update, mock_image_get):