#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Standard Library
import fcntl
import json
import logging
import os
import queue
import socket
import struct
import sys
import threading
import uuid
from dataclasses import dataclass
from functools import cache
from os.path import dirname, join

logger = logging.getLogger(__name__)


@dataclass
class Metadata:
    uri = ""
    position = 0
    current_offset = 0
    duration = 0
    state = "NO_MEDIA_PRESENT"
    volume = 100

    video_loaded = threading.Event()
    is_muted = threading.Event()

    cec_queue = queue.Queue()
    gui_queue = queue.Queue()


def to_time(seconds):
    if seconds == -1:
        return "00:00:00"
    if isinstance(seconds, str):
        return seconds
    hours = int(seconds // 3600)
    minutes = int((seconds % 3600) // 60)
    remaining_seconds = int(seconds % 60)
    return f"{hours}:{minutes:02}:{remaining_seconds:02}"


def from_time(timestr):
    hours, minutes, seconds = timestr.split(":")
    return float(hours) * 3600 + float(minutes) * 60 + float(seconds)


def get_friendly_name():
    return socket.gethostname().replace("-", " ").title().replace("Ironcast", "IronCast")


def get_uuid():
    return get_config()["uuid"]


def get_config():
    file = join(dirname(__file__), ".ironcast_config")
    if os.path.exists(file):
        with open(file, "r", encoding="utf-8") as f:
            data = json.load(f)
    else:
        data = {
            "uuid": str(uuid.uuid4()).rsplit("-", 1)[0],
        }
        with open(file, "w", encoding="utf-8") as f:
            json.dump(data, f)
    return data


def make_uuid():
    return "uuid:" + str(uuid.uuid4()).rsplit("-", 1)[0]


@cache
def get_ip_address():
    platform = sys.platform
    if not platform.startswith("linux"):
        return []

    sysnet = "/sys/class/net"
    ifnames = os.listdir(sysnet) if os.path.exists(sysnet) else []
    ip_list = []

    try:
        for ifname in ifnames:
            try:
                s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
                ip = socket.inet_ntoa(
                    fcntl.ioctl(
                        s.fileno(),
                        0x8915,  # SIOCGIFADDR
                        struct.pack("256s", bytes(ifname[:15], "utf-8")),
                    )[20:24]
                )
                if ip.startswith("192.168."):
                    ip_list.append(ip)
            except OSError:
                # this interface doens't have an address.
                pass
    finally:
        s.close()

    if not ip_list:
        logger.error("Unable to determine server IP. Had %s with no found IPs.", ", ".join(ifnames))

    ip_list.sort()
    return ip_list[0]


ironcast = Metadata()
