# Copyright 2014 Budapest University of Technology and Economics (BME IK)
#
# This file is part of CIRCLE Cloud.
#
# CIRCLE is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# CIRCLE is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with CIRCLE.  If not, see <http://www.gnu.org/licenses/>.
from __future__ import unicode_literals, absolute_import

import logging

import openstack_api
from braces.views import LoginRequiredMixin
from dashboard.models import GroupProfile, Favourite
from django.conf import settings
from django.contrib.auth.models import Group, User
from django.core.cache import cache
from django.views.generic import TemplateView
from vm.models import Instance, InstanceTemplate
from dashboard.views.vm import vm_ops
from network.models import Vxlan

from ..store_api import Store

logger = logging.getLogger(__name__)


class IndexView(LoginRequiredMixin, TemplateView):
    template_name = "dashboard/index.html"

    def get_context_data(self, **kwargs):
        user = self.request.user
        context = super(IndexView, self).get_context_data(**kwargs)

        instances = openstack_api.nova.server_list(self.request)[0] #TODO: flatten?
        quotas = openstack_api.nova.tenant_quota_get(self.request, user.project_id)

        # instances
        favs = [f.instance for f in Favourite.objects.filter(user=user.id)]
        fav_instances = [
            i for i in instances if i.id in favs
        ]
        display = list(fav_instances) + list(set(instances) - set(fav_instances))
        for d in display:
            d.fav = True if d in fav_instances else False

        context.update({
            'instances': display[:5],
            'more_instances': len(instances) - len(instances[:5]),
            'max_instances': quotas.get("instances").limit
        })

        running = [i for i in instances if i.status == "ACTIVE"]
        stopped = [i for i in instances if i.status != "ACTIVE"]

        context.update({
            'running_vms': running[:20],
            'running_vm_num': len(running),
            'stopped_vm_num': len(stopped)
        })

        # nodes
        if user.has_perm('vm.view_statistics'):
            nodes = Node.objects.all()
            context.update({
                'nodes': nodes[:5],
                'more_nodes': nodes.count() - len(nodes[:5]),
                'sum_node_num': nodes.count(),
                'node_num': {
                    'running': Node.get_state_count(True, True),
                    'missing': Node.get_state_count(False, True),
                    'disabled': Node.get_state_count(True, False),
                    'offline': Node.get_state_count(False, False)
                }
            })

        # groups
        if user.has_module_perms('auth'):
            profiles = GroupProfile.get_objects_with_level('operator', user)
            groups = Group.objects.filter(groupprofile__in=profiles)
            context.update({
                'groups': groups[:5],
                'more_groups': groups.count() - len(groups[:5]),
            })

        # users
        if user.has_module_perms('auth.change_user'):
            users = User.objects.all()
            context.update({
                'users': users[:5],
                'more_users': users.count() - len(users[:5]),
            })

        # template
        images = openstack_api.glance.image_list_detailed(self.request)[0]  # TODO: why nested lists?
        snapshot_ids = [
            i.id for i in images if hasattr(i, 'image_location') and i.image_location == 'snapshot'
        ]
        context['templates'] = InstanceTemplate.objects.filter(image_id__in=snapshot_ids)

        # vxlan
        all_vxlans = openstack_api.neutron.network_list_for_tenant(self.request, self.request.user.tenant_id)
        tenant_networks = [n for n in all_vxlans
                           if n.name not in settings.FLAT_EXTERNAL_NETWORKS + settings.SMART_EXTERNAL_NETWORKS]
        context['vxlans'] = tenant_networks[:5]

        # toplist
        if settings.STORE_URL:
            cache_key = "files-%d" % self.request.user.pk
            files = cache.get(cache_key)
            if not files:
                try:
                    store = Store(self.request.user)
                    toplist = store.toplist()
                    quota = store.get_quota()
                    files = {'toplist': toplist, 'quota': quota}
                except Exception:
                    logger.exception("Unable to get tolist for %s",
                                     unicode(self.request.user))
                    files = {'toplist': []}
                cache.set(cache_key, files, 300)

            context['files'] = files
        else:
            context['no_store'] = True

        return context


# class HelpView(TemplateView):
#
#     def get_context_data(self, *args, **kwargs):
#         ctx = super(HelpView, self).get_context_data(*args, **kwargs)
#         operations = [(o, Instance._ops[o.op])
#                       for o in vm_ops.values() if o.show_in_toolbar]
#         ctx.update({"saml": hasattr(settings, "SAML_CONFIG"),
#                     "operations": operations,
#                     "store": settings.STORE_URL})
#         return ctx
#
#
# class ResizeHelpView(TemplateView):
#     template_name = "info/resize.html"
#
#
# class OpenSearchDescriptionView(TemplateView):
#     template_name = "dashboard/vm-opensearch.xml"
#     content_type = "application/opensearchdescription+xml"
#
#     def get_context_data(self, **kwargs):
#         context = super(OpenSearchDescriptionView, self).get_context_data(
#             **kwargs)
#         context['url'] = self.request.build_absolute_uri(
#             reverse("dashboard.views.vm-list"))
#         return context
