# 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.

"""
Admin views for managing volumes and snapshots.
"""
from collections import OrderedDict

from django.conf import settings
from django.urls import reverse
from django.urls import reverse_lazy
from django.utils.translation import ugettext_lazy as _

from horizon import exceptions
from horizon import forms
from horizon import tables
from horizon.utils import memoized

from openstack_dashboard.api import cinder
from openstack_dashboard.api import keystone
from openstack_dashboard.dashboards.admin.volumes \
    import forms as volumes_forms
from openstack_dashboard.dashboards.admin.volumes \
    import tables as volumes_tables
from openstack_dashboard.dashboards.admin.volumes \
    import tabs as volumes_tabs
from openstack_dashboard.dashboards.project.volumes \
    import views as volumes_views


class VolumesView(tables.PagedTableMixin, volumes_views.VolumeTableMixIn,
                  tables.DataTableView):
    table_class = volumes_tables.VolumesTable
    page_title = _("Volumes")

    FILTERS_MAPPING = {'bootable': {_('yes'): 'true', _('no'): 'false'},
                       'encrypted': {_('yes'): True, _('no'): False}}

    def get_data(self):
        default_filters = {'all_tenants': True}

        filters = self.get_filters(default_filters.copy())
        filter_first = getattr(settings, 'FILTER_DATA_FIRST', {})
        volumes = []

        self.table.needs_filter_first = False

        if filter_first.get('admin.volumes', False) and \
                len(filters) == len(default_filters):
            self.table.needs_filter_first = True
            return volumes

        if 'project' in filters:
            # Keystone returns a tuple ([],false) where the first element is
            # tenant list that's why the 0 is hardcoded below
            tenants = keystone.tenant_list(self.request)[0]
            tenant_ids = [t.id for t in tenants
                          if t.name == filters['project']]
            if not tenant_ids:
                return []
            del filters['project']
            for id in tenant_ids:
                filters['project_id'] = id
                volumes += self._get_volumes(search_opts=filters)
        else:
            volumes = self._get_volumes(search_opts=filters)

        attached_instance_ids = self._get_attached_instance_ids(volumes)
        instances = self._get_instances(search_opts={'all_tenants': True},
                                        instance_ids=attached_instance_ids)
        volume_ids_with_snapshots = self._get_volumes_ids_with_snapshots(
            search_opts={'all_tenants': True})
        self._set_volume_attributes(
            volumes, instances, volume_ids_with_snapshots)

        # Gather our tenants to correlate against IDs
        try:
            tenants, has_more = keystone.tenant_list(self.request)
        except Exception:
            tenants = []
            msg = _('Unable to retrieve volume project information.')
            exceptions.handle(self.request, msg)

        tenant_dict = OrderedDict([(t.id, t) for t in tenants])
        for volume in volumes:
            tenant_id = getattr(volume, "os-vol-tenant-attr:tenant_id", None)
            tenant = tenant_dict.get(tenant_id, None)
            volume.tenant_name = getattr(tenant, "name", None)

        return volumes

    def get_filters(self, filters):
        self.table = self._tables['volumes']
        self.handle_server_filter(self.request, table=self.table)
        self.update_server_filter_action(self.request, table=self.table)
        filters = super(VolumesView, self).get_filters(filters,
                                                       self.FILTERS_MAPPING)
        return filters


class DetailView(volumes_views.DetailView):
    tab_group_class = volumes_tabs.VolumeDetailTabs

    def get_context_data(self, **kwargs):
        context = super(DetailView, self).get_context_data(**kwargs)
        table = volumes_tables.VolumesTable(self.request)
        context["actions"] = table.render_row_actions(context["volume"])
        return context

    def get_search_opts(self, volume):
        search_opts = super(DetailView, self).get_search_opts(volume)
        search_opts['all_tenants'] = True
        return search_opts

    def get_redirect_url(self):
        return reverse('horizon:admin:volumes:index')


class ManageVolumeView(forms.ModalFormView):
    form_class = volumes_forms.ManageVolume
    template_name = 'admin/volumes/manage_volume.html'
    form_id = "manage_volume_modal"
    submit_label = _("Manage")
    success_url = reverse_lazy('horizon:admin:volumes:index')
    submit_url = reverse_lazy('horizon:admin:volumes:manage')
    cancel_url = reverse_lazy("horizon:admin:volumes:index")
    page_title = _("Manage Volume")

    def get_context_data(self, **kwargs):
        context = super(ManageVolumeView, self).get_context_data(**kwargs)
        return context


class UnmanageVolumeView(forms.ModalFormView):
    form_class = volumes_forms.UnmanageVolume
    template_name = 'admin/volumes/unmanage_volume.html'
    form_id = "unmanage_volume_modal"
    submit_label = _("Unmanage")
    success_url = reverse_lazy('horizon:admin:volumes:index')
    submit_url = 'horizon:admin:volumes:unmanage'
    cancel_url = reverse_lazy("horizon:admin:volumes:index")
    page_title = _("Unmanage Volume")

    def get_context_data(self, **kwargs):
        context = super(UnmanageVolumeView, self).get_context_data(**kwargs)
        args = (self.kwargs['volume_id'],)
        context['submit_url'] = reverse(self.submit_url, args=args)
        return context

    @memoized.memoized_method
    def get_data(self):
        try:
            volume_id = self.kwargs['volume_id']
            volume = cinder.volume_get(self.request, volume_id)
        except Exception:
            exceptions.handle(self.request,
                              _('Unable to retrieve volume details.'),
                              redirect=self.success_url)
        return volume

    def get_initial(self):
        volume = self.get_data()
        return {'volume_id': self.kwargs["volume_id"],
                'name': volume.name,
                'host': getattr(volume, "os-vol-host-attr:host")}


class MigrateVolumeView(forms.ModalFormView):
    form_class = volumes_forms.MigrateVolume
    template_name = 'admin/volumes/migrate_volume.html'
    form_id = "migrate_volume_modal"
    submit_label = _("Migrate")
    success_url = reverse_lazy('horizon:admin:volumes:index')
    submit_url = 'horizon:admin:volumes:migrate'
    cancel_url = reverse_lazy("horizon:admin:volumes:index")
    page_title = _("Migrate Volume")

    def get_context_data(self, **kwargs):
        context = super(MigrateVolumeView, self).get_context_data(**kwargs)
        args = (self.kwargs['volume_id'],)
        context['submit_url'] = reverse(self.submit_url, args=args)
        return context

    @memoized.memoized_method
    def get_data(self):
        try:
            volume_id = self.kwargs['volume_id']
            volume = cinder.volume_get(self.request, volume_id)
        except Exception:
            exceptions.handle(self.request,
                              _('Unable to retrieve volume details.'),
                              redirect=self.success_url)
        return volume

    @memoized.memoized_method
    def get_hosts(self):
        try:
            return cinder.pool_list(self.request)
        except Exception:
            exceptions.handle(self.request,
                              _('Unable to retrieve pools information.'),
                              redirect=self.success_url)

    def get_initial(self):
        volume = self.get_data()
        return {'volume_id': self.kwargs["volume_id"],
                'name': volume.name,
                'current_host': getattr(volume, "os-vol-host-attr:host"),
                'hosts': self.get_hosts()}


class UpdateStatusView(forms.ModalFormView):
    form_class = volumes_forms.UpdateStatus
    modal_id = "update_volume_status_modal"
    template_name = 'admin/volumes/update_status.html'
    submit_label = _("Update Status")
    submit_url = "horizon:admin:volumes:update_status"
    success_url = reverse_lazy('horizon:admin:volumes:index')
    page_title = _("Update Volume Status")

    def get_context_data(self, **kwargs):
        context = super(UpdateStatusView, self).get_context_data(**kwargs)
        context["volume_id"] = self.kwargs['volume_id']
        args = (self.kwargs['volume_id'],)
        context['submit_url'] = reverse(self.submit_url, args=args)
        return context

    @memoized.memoized_method
    def get_data(self):
        try:
            volume_id = self.kwargs['volume_id']
            volume = cinder.volume_get(self.request, volume_id)
        except Exception:
            exceptions.handle(self.request,
                              _('Unable to retrieve volume details.'),
                              redirect=self.success_url)
        return volume

    def get_initial(self):
        volume = self.get_data()
        return {'volume_id': self.kwargs["volume_id"],
                'status': volume.status}

[((45, 17, 45, 29), 'django.utils.translation.ugettext_lazy', '_', ({(45, 19, 45, 28): '"""Volumes"""'}, {}), "('Volumes')", True, 'from django.utils.translation import ugettext_lazy as _\n'), ((134, 19, 134, 30), 'django.utils.translation.ugettext_lazy', '_', ({(134, 21, 134, 29): '"""Manage"""'}, {}), "('Manage')", True, 'from django.utils.translation import ugettext_lazy as _\n'), ((135, 18, 135, 61), 'django.urls.reverse_lazy', 'reverse_lazy', ({(135, 31, 135, 60): '"""horizon:admin:volumes:index"""'}, {}), "('horizon:admin:volumes:index')", False, 'from django.urls import reverse_lazy\n'), ((136, 17, 136, 61), 'django.urls.reverse_lazy', 'reverse_lazy', ({(136, 30, 136, 60): '"""horizon:admin:volumes:manage"""'}, {}), "('horizon:admin:volumes:manage')", False, 'from django.urls import reverse_lazy\n'), ((137, 17, 137, 60), 'django.urls.reverse_lazy', 'reverse_lazy', ({(137, 30, 137, 59): '"""horizon:admin:volumes:index"""'}, {}), "('horizon:admin:volumes:index')", False, 'from django.urls import reverse_lazy\n'), ((138, 17, 138, 35), 'django.utils.translation.ugettext_lazy', '_', ({(138, 19, 138, 34): '"""Manage Volume"""'}, {}), "('Manage Volume')", True, 'from django.utils.translation import ugettext_lazy as _\n'), ((149, 19, 149, 32), 'django.utils.translation.ugettext_lazy', '_', ({(149, 21, 149, 31): '"""Unmanage"""'}, {}), "('Unmanage')", True, 'from django.utils.translation import ugettext_lazy as _\n'), ((150, 18, 150, 61), 'django.urls.reverse_lazy', 'reverse_lazy', ({(150, 31, 150, 60): '"""horizon:admin:volumes:index"""'}, {}), "('horizon:admin:volumes:index')", False, 'from django.urls import reverse_lazy\n'), ((152, 17, 152, 60), 'django.urls.reverse_lazy', 'reverse_lazy', ({(152, 30, 152, 59): '"""horizon:admin:volumes:index"""'}, {}), "('horizon:admin:volumes:index')", False, 'from django.urls import reverse_lazy\n'), ((153, 17, 153, 37), 'django.utils.translation.ugettext_lazy', '_', ({(153, 19, 153, 36): '"""Unmanage Volume"""'}, {}), "('Unmanage Volume')", True, 'from django.utils.translation import ugettext_lazy as _\n'), ((183, 19, 183, 31), 'django.utils.translation.ugettext_lazy', '_', ({(183, 21, 183, 30): '"""Migrate"""'}, {}), "('Migrate')", True, 'from django.utils.translation import ugettext_lazy as _\n'), ((184, 18, 184, 61), 'django.urls.reverse_lazy', 'reverse_lazy', ({(184, 31, 184, 60): '"""horizon:admin:volumes:index"""'}, {}), "('horizon:admin:volumes:index')", False, 'from django.urls import reverse_lazy\n'), ((186, 17, 186, 60), 'django.urls.reverse_lazy', 'reverse_lazy', ({(186, 30, 186, 59): '"""horizon:admin:volumes:index"""'}, {}), "('horizon:admin:volumes:index')", False, 'from django.urls import reverse_lazy\n'), ((187, 17, 187, 36), 'django.utils.translation.ugettext_lazy', '_', ({(187, 19, 187, 35): '"""Migrate Volume"""'}, {}), "('Migrate Volume')", True, 'from django.utils.translation import ugettext_lazy as _\n'), ((227, 19, 227, 37), 'django.utils.translation.ugettext_lazy', '_', ({(227, 21, 227, 36): '"""Update Status"""'}, {}), "('Update Status')", True, 'from django.utils.translation import ugettext_lazy as _\n'), ((229, 18, 229, 61), 'django.urls.reverse_lazy', 'reverse_lazy', ({(229, 31, 229, 60): '"""horizon:admin:volumes:index"""'}, {}), "('horizon:admin:volumes:index')", False, 'from django.urls import reverse_lazy\n'), ((230, 17, 230, 42), 'django.utils.translation.ugettext_lazy', '_', ({(230, 19, 230, 41): '"""Update Volume Status"""'}, {}), "('Update Volume Status')", True, 'from django.utils.translation import ugettext_lazy as _\n'), ((95, 22, 95, 63), 'collections.OrderedDict', 'OrderedDict', ({(95, 34, 95, 62): '[(t.id, t) for t in tenants]'}, {}), '([(t.id, t) for t in tenants])', False, 'from collections import OrderedDict\n'), ((117, 16, 117, 57), 'openstack_dashboard.dashboards.admin.volumes.tables.VolumesTable', 'volumes_tables.VolumesTable', ({(117, 44, 117, 56): 'self.request'}, {}), '(self.request)', True, 'from openstack_dashboard.dashboards.admin.volumes import tables as volumes_tables\n'), ((127, 15, 127, 53), 'django.urls.reverse', 'reverse', ({(127, 23, 127, 52): '"""horizon:admin:volumes:index"""'}, {}), "('horizon:admin:volumes:index')", False, 'from django.urls import reverse\n'), ((158, 32, 158, 67), 'django.urls.reverse', 'reverse', (), '', False, 'from django.urls import reverse\n'), ((192, 32, 192, 67), 'django.urls.reverse', 'reverse', (), '', False, 'from django.urls import reverse\n'), ((236, 32, 236, 67), 'django.urls.reverse', 'reverse', (), '', False, 'from django.urls import reverse\n'), ((47, 36, 47, 44), 'django.utils.translation.ugettext_lazy', '_', ({(47, 38, 47, 43): '"""yes"""'}, {}), "('yes')", True, 'from django.utils.translation import ugettext_lazy as _\n'), ((47, 54, 47, 61), 'django.utils.translation.ugettext_lazy', '_', ({(47, 56, 47, 60): '"""no"""'}, {}), "('no')", True, 'from django.utils.translation import ugettext_lazy as _\n'), ((48, 37, 48, 45), 'django.utils.translation.ugettext_lazy', '_', ({(48, 39, 48, 44): '"""yes"""'}, {}), "('yes')", True, 'from django.utils.translation import ugettext_lazy as _\n'), ((48, 53, 48, 60), 'django.utils.translation.ugettext_lazy', '_', ({(48, 55, 48, 59): '"""no"""'}, {}), "('no')", True, 'from django.utils.translation import ugettext_lazy as _\n'), ((89, 32, 89, 66), 'openstack_dashboard.api.keystone.tenant_list', 'keystone.tenant_list', ({(89, 53, 89, 65): 'self.request'}, {}), '(self.request)', False, 'from openstack_dashboard.api import keystone\n'), ((165, 21, 165, 63), 'openstack_dashboard.api.cinder.volume_get', 'cinder.volume_get', ({(165, 39, 165, 51): 'self.request', (165, 53, 165, 62): 'volume_id'}, {}), '(self.request, volume_id)', False, 'from openstack_dashboard.api import cinder\n'), ((199, 21, 199, 63), 'openstack_dashboard.api.cinder.volume_get', 'cinder.volume_get', ({(199, 39, 199, 51): 'self.request', (199, 53, 199, 62): 'volume_id'}, {}), '(self.request, volume_id)', False, 'from openstack_dashboard.api import cinder\n'), ((209, 19, 209, 49), 'openstack_dashboard.api.cinder.pool_list', 'cinder.pool_list', ({(209, 36, 209, 48): 'self.request'}, {}), '(self.request)', False, 'from openstack_dashboard.api import cinder\n'), ((243, 21, 243, 63), 'openstack_dashboard.api.cinder.volume_get', 'cinder.volume_get', ({(243, 39, 243, 51): 'self.request', (243, 53, 243, 62): 'volume_id'}, {}), '(self.request, volume_id)', False, 'from openstack_dashboard.api import cinder\n'), ((67, 22, 67, 56), 'openstack_dashboard.api.keystone.tenant_list', 'keystone.tenant_list', ({(67, 43, 67, 55): 'self.request'}, {}), '(self.request)', False, 'from openstack_dashboard.api import keystone\n'), ((92, 18, 92, 69), 'django.utils.translation.ugettext_lazy', '_', ({(92, 20, 92, 68): '"""Unable to retrieve volume project information."""'}, {}), "('Unable to retrieve volume project information.')", True, 'from django.utils.translation import ugettext_lazy as _\n'), ((93, 12, 93, 48), 'horizon.exceptions.handle', 'exceptions.handle', ({(93, 30, 93, 42): 'self.request', (93, 44, 93, 47): 'msg'}, {}), '(self.request, msg)', False, 'from horizon import exceptions\n'), ((168, 30, 168, 69), 'django.utils.translation.ugettext_lazy', '_', ({(168, 32, 168, 68): '"""Unable to retrieve volume details."""'}, {}), "('Unable to retrieve volume details.')", True, 'from django.utils.translation import ugettext_lazy as _\n'), ((202, 30, 202, 69), 'django.utils.translation.ugettext_lazy', '_', ({(202, 32, 202, 68): '"""Unable to retrieve volume details."""'}, {}), "('Unable to retrieve volume details.')", True, 'from django.utils.translation import ugettext_lazy as _\n'), ((212, 30, 212, 72), 'django.utils.translation.ugettext_lazy', '_', ({(212, 32, 212, 71): '"""Unable to retrieve pools information."""'}, {}), "('Unable to retrieve pools information.')", True, 'from django.utils.translation import ugettext_lazy as _\n'), ((246, 30, 246, 69), 'django.utils.translation.ugettext_lazy', '_', ({(246, 32, 246, 68): '"""Unable to retrieve volume details."""'}, {}), "('Unable to retrieve volume details.')", True, 'from django.utils.translation import ugettext_lazy as _\n')]