"""Command line tool to communicate withthe NetBox API."""
from typing import Any, Dict, List

import click
import pandas as pd

from gso.services.netbox_client import NetBoxClient


def convert_to_table(data: List[Dict[str, Any]], fields: List[str]) -> pd.DataFrame:
    if not data:
        raise ValueError("No data is available for your request")

    df = pd.DataFrame(data)
    if fields:
        df = df[fields]

    return df


@click.group()
def cli() -> None:
    pass


@cli.group()
def create() -> None:
    pass


@create.command()
@click.option("--fqdn", prompt="Enter device name", help="Device name")
@click.option("--model", default="vmx", help="Device model")
def device(fqdn: str, model: str) -> None:
    click.echo(f"Creating device: fqdn={fqdn}, model={model}")
    new_device = NetBoxClient().create_device(fqdn, model)
    click.echo(new_device)


@create.command()
@click.option("--name", help="Interfacename")
@click.option("--type", default="10gbase-t", help="Interface type, default is 10GBASE-T")
@click.option("--speed", default="1000", help="Interface speed , default is 1000")
@click.option("--fqdn", help="Device where to create interface")
def interface(name: str, type: str, speed: str, fqdn: str) -> None:
    click.echo(f"Creating interface: name={name}, speed={speed}, fqdn={fqdn}")
    new_interface = NetBoxClient().create_interface(name, type, speed, fqdn)
    click.echo(new_interface)


@create.command()
@click.option("--name", help="Manufacturer name")
@click.option("--slug", help="Short name for manufacturer")
def manufacturer(name: str, slug: str) -> None:
    click.echo(f"Creating manufacturer: name={name}")
    manufacturer = NetBoxClient().create_device_manufacturer(name, slug)
    click.echo(manufacturer)


@create.command()
@click.option("--manufacturer", help="Manufacturer for device")
@click.option("--model", help="Model for device")
@click.option("--slug", help="Short name for manufacturer")
def device_type(manufacturer: str, model: str, slug: str) -> None:
    click.echo(f"Creating device type: manufacturer={manufacturer} model = {model}")
    device_type = NetBoxClient().create_device_type(manufacturer, model, slug)
    click.echo(device_type)


@create.command()
@click.option("--name", help="Name for device role")
@click.option("--slug", help="Short name for device role")
def device_role(name: str, slug: str) -> None:
    click.echo(f"Creating device role: name={name}")
    device_role = NetBoxClient().create_device_role(name, slug)
    click.echo(device_role)


@create.command()
@click.option("--name", help="Name for device site")
@click.option("--slug", help="Short name for device site")
def device_site(name: str, slug: str) -> None:
    click.echo(f"Creating device site: name={name}")
    device_site = NetBoxClient().create_device_site(name, slug)
    click.echo(device_site)


create.add_command(device)
create.add_command(interface)
create.add_command(manufacturer)
create.add_command(device_type)
create.add_command(device_role)
create.add_command(device_site)


# Define list commands here
@cli.group()
def list() -> None:
    pass


@list.command()
@click.option("--fqdn", help="Device name to list interfaces")
@click.option("--speed", default="1000", help="Interface speed to list interfaces (default 1000=1G)")
def interfaces(fqdn: str, speed: str) -> None:
    click.echo(f"Listing all interfaces for: device with fqdn={fqdn}, speed={speed}")
    interface_list = NetBoxClient().get_interfaces_by_device(fqdn, speed)
    display_fields = ["name", "enabled", "mark_connected", "custom_fields", "lag", "speed"]
    iface_list = []
    for iface in interface_list:
        iface_list.append(dict(iface))

    table = convert_to_table(iface_list, display_fields)
    click.echo(table)


@list.command()
def devices() -> None:
    click.echo("Listing all devices:")
    device_list = NetBoxClient().get_all_devices()
    display_fields = ["name", "device_type"]
    devices = []
    for device in device_list:
        devices.append(dict(device))

    table = convert_to_table(devices, display_fields)
    click.echo(table)


list.add_command(interfaces)
list.add_command(devices)


# Define here attach command
@cli.group()
def attach() -> None:
    pass


@attach.command()
@click.option("--fqdn", help="Device name where to attach interface to lag")
@click.option("--iface", help="Interface name to attach to lag")
@click.option("--lag", help="LAG name to attach interface")
def interface_to_lag(fqdn: str, iface: str, lag: str) -> None:
    click.echo(f"Attaching interface to lag: device ={fqdn}, interface name={iface} to lag={lag}")
    new_iface = NetBoxClient().attach_interface_to_lag(fqdn, lag, iface)
    click.echo(new_iface)


attach.add_command(interface_to_lag)


# The reserve command
@cli.group()
def reserve() -> None:
    pass


@reserve.command()
@click.option("--fqdn", help="Device name where to get interface to reserve")
@click.option("--iface", help="Interface name to reserve")
def reserve_interface(fqdn: str, iface: str) -> None:
    click.echo(f"Reserving interface: device ={fqdn}, interface name={iface}")
    reserved_iface = NetBoxClient().reserve_interface(fqdn, iface)
    click.echo(reserved_iface)


reserve.add_command(reserve_interface)


if __name__ == "__main__":
    cli()