import django_tables2 as tables
from django.utils.translation import gettext_lazy as _

from dcim.tables.devices import BaseInterfaceTable
from netbox.tables import NetBoxTable, PrimaryModelTable, columns
from tenancy.tables import ContactsColumnMixin, TenancyColumnsMixin
from utilities.templatetags.helpers import humanize_disk_capacity, humanize_ram_capacity

from ..models import VirtualDisk, VirtualMachine, VirtualMachineType, VMInterface
from .template_code import *

__all__ = (
    'VMInterfaceTable',
    'VirtualDiskTable',
    'VirtualMachineTable',
    'VirtualMachineTypeTable',
    'VirtualMachineVMInterfaceTable',
    'VirtualMachineVirtualDiskTable',
)

#
# Virtual machine types
#


class VirtualMachineTypeTable(PrimaryModelTable):
    name = tables.Column(
        verbose_name=_('Name'),
        linkify=True,
    )
    default_platform = tables.Column(
        verbose_name=_('Default platform'),
        linkify=True,
    )
    virtual_machine_count = tables.Column(
        verbose_name=_('VM count')
    )
    tags = columns.TagColumn(
        url_name='virtualization:virtualmachinetype_list'
    )

    class Meta(PrimaryModelTable.Meta):
        model = VirtualMachineType
        fields = (
            'pk', 'id', 'name', 'slug', 'default_platform', 'default_vcpus', 'default_memory', 'virtual_machine_count',
            'description', 'comments', 'tags', 'created', 'last_updated',
        )
        default_columns = (
            'pk', 'name', 'default_platform', 'default_vcpus', 'default_memory', 'virtual_machine_count', 'description',
        )

    def render_default_memory(self, value):
        return humanize_ram_capacity(value)


#
# Virtual machines
#


class VirtualMachineTable(TenancyColumnsMixin, ContactsColumnMixin, PrimaryModelTable):
    name = tables.Column(
        verbose_name=_('Name'),
        linkify=True
    )
    virtual_machine_type = tables.Column(
        verbose_name=_('Type'),
        linkify=True,
    )
    status = columns.ChoiceFieldColumn(
        verbose_name=_('Status'),
    )
    start_on_boot = columns.ChoiceFieldColumn(
        verbose_name=_('Start on boot'),
    )
    site = tables.Column(
        verbose_name=_('Site'),
        linkify=True
    )
    cluster = tables.Column(
        verbose_name=_('Cluster'),
        linkify=True
    )
    device = tables.Column(
        verbose_name=_('Device'),
        linkify=True
    )
    role = columns.ColoredLabelColumn(
        verbose_name=_('Role'),
    )
    platform = tables.Column(
        linkify=True,
        verbose_name=_('Platform')
    )
    primary_ip4 = tables.Column(
        linkify=True,
        verbose_name=_('IPv4 Address')
    )
    primary_ip6 = tables.Column(
        linkify=True,
        verbose_name=_('IPv6 Address')
    )
    primary_ip = tables.Column(
        linkify=True,
        order_by=('primary_ip4', 'primary_ip6'),
        verbose_name=_('IP Address')
    )
    tags = columns.TagColumn(
        url_name='virtualization:virtualmachine_list'
    )
    interface_count = tables.Column(
        verbose_name=_('Interfaces')
    )
    virtual_disk_count = tables.Column(
        verbose_name=_('Virtual Disks')
    )
    config_template = tables.Column(
        verbose_name=_('Config Template'),
        linkify=True
    )
    disk = tables.Column(
        verbose_name=_('Disk'),
    )

    class Meta(PrimaryModelTable.Meta):
        model = VirtualMachine
        fields = (
            'pk', 'id', 'name', 'virtual_machine_type', 'role', 'status', 'start_on_boot', 'site', 'cluster', 'device',
            'platform', 'primary_ip4', 'primary_ip6', 'primary_ip', 'vcpus', 'memory', 'disk', 'description', 'serial',
            'tenant_group', 'tenant', 'contacts', 'comments', 'tags', 'config_template', 'created', 'last_updated',
        )
        default_columns = (
            'pk', 'name', 'virtual_machine_type', 'role', 'status', 'site', 'cluster', 'tenant',
            'vcpus', 'memory', 'disk', 'primary_ip',
        )

    def render_memory(self, value):
        return humanize_ram_capacity(value)

    def render_disk(self, value):
        return humanize_disk_capacity(value)


#
# VM components
#

class VMInterfaceTable(BaseInterfaceTable):
    virtual_machine = tables.Column(
        verbose_name=_('Virtual Machine'),
        linkify=True
    )
    name = tables.Column(
        verbose_name=_('Name'),
        linkify=True
    )
    vrf = tables.Column(
        verbose_name=_('VRF'),
        linkify=True
    )
    tags = columns.TagColumn(
        url_name='virtualization:vminterface_list'
    )

    class Meta(NetBoxTable.Meta):
        model = VMInterface
        fields = (
            'pk', 'id', 'name', 'virtual_machine', 'enabled', 'mtu', 'mode', 'description', 'tags', 'vrf',
            'primary_mac_address', 'l2vpn', 'tunnel', 'ip_addresses', 'fhrp_groups', 'untagged_vlan', 'tagged_vlans',
            'qinq_svlan', 'created', 'last_updated', 'vlan_translation_policy',
        )
        default_columns = ('pk', 'name', 'virtual_machine', 'enabled', 'description')


class VirtualMachineVMInterfaceTable(VMInterfaceTable):
    parent = tables.Column(
        verbose_name=_('Parent'),
        linkify=True
    )
    bridge = tables.Column(
        verbose_name=_('Bridge'),
        linkify=True
    )
    actions = columns.ActionsColumn(
        actions=('edit', 'delete'),
        extra_buttons=VMINTERFACE_BUTTONS
    )

    class Meta(NetBoxTable.Meta):
        model = VMInterface
        fields = (
            'pk', 'id', 'name', 'enabled', 'parent', 'bridge', 'primary_mac_address', 'mtu', 'mode', 'description',
            'tags', 'vrf', 'l2vpn', 'tunnel', 'ip_addresses', 'fhrp_groups', 'untagged_vlan', 'tagged_vlans',
            'qinq_svlan', 'actions',
        )
        default_columns = ('pk', 'name', 'enabled', 'primary_mac_address', 'mtu', 'mode', 'description', 'ip_addresses')
        row_attrs = {
            'data-name': lambda record: record.name,
            'data-virtual': lambda record: "true",
            'data-enabled': lambda record: "true" if record.enabled else "false",
        }


class VirtualDiskTable(NetBoxTable):
    virtual_machine = tables.Column(
        verbose_name=_('Virtual Machine'),
        linkify=True
    )
    name = tables.Column(
        verbose_name=_('Name'),
        linkify=True
    )
    size = tables.Column(
        verbose_name=_('Size')
    )
    tags = columns.TagColumn(
        url_name='virtualization:virtualdisk_list'
    )

    class Meta(NetBoxTable.Meta):
        model = VirtualDisk
        fields = (
            'pk', 'id', 'virtual_machine', 'name', 'size', 'description', 'tags',
        )
        default_columns = ('pk', 'name', 'virtual_machine', 'size', 'description')
        row_attrs = {
            'data-name': lambda record: record.name,
        }

    def render_size(self, value):
        return humanize_disk_capacity(value)


class VirtualMachineVirtualDiskTable(VirtualDiskTable):
    actions = columns.ActionsColumn(
        actions=('edit', 'delete'),
    )

    class Meta(VirtualDiskTable.Meta):
        fields = (
            'pk', 'id', 'name', 'size', 'description', 'tags', 'actions',
        )
        default_columns = ('pk', 'name', 'size', 'description')
