import dataclasses
import json
import sys
from pathlib import Path

import platformdirs

from flandre import DEV_PROJECT_FOLDER

ISDEV = False
if '--dev' in sys.argv:
    ISDEV = True

CONFIG_FOLDER = platformdirs.user_config_path('Flandre', 'Scarlet')

if ISDEV:
    CONFIG_FOLDER = DEV_PROJECT_FOLDER / 'config'

DS = DEV_PROJECT_FOLDER / '@DS'
DS.mkdir(exist_ok=True, parents=True)

SOFTWARE_CONFIG_PATH = CONFIG_FOLDER / 'software.json'


@dataclasses.dataclass
class SoftwareConfig:
    def s(self, host, port, proto='tcp'):
        return f'{proto}://{host}:{port}'

    data_folder: Path = DS

    @property
    def imaging_config_folder(self):
        p = CONFIG_FOLDER / 'imaging'
        p.mkdir(exist_ok=True, parents=True)
        return p

    @property
    def device_config_folder(self):
        p = CONFIG_FOLDER / 'device'
        p.mkdir(exist_ok=True, parents=True)
        return p

    video_height: int = 1920
    video_width: int = 1080

    live_ip: str = '11.6.1.71'
    live_push_port: int = 5555
    live_rep_port: int = 5556
    device_py_rep_port: int = 5558

    @property
    def live_push_socket(self):
        return f'tcp://{self.live_ip}:{self.live_push_port}'

    @property
    def live_rep_socket(self):
        return f'tcp://{self.live_ip}:{self.live_rep_port}'

    @property
    def live_rep_socket_http(self):
        return f'http://{self.live_ip}:{self.live_rep_port}'

    @property
    def device_py_rep_socket(self):
        return f'tcp://{self.live_ip}:{self.device_py_rep_port}'

    playback_port: int = 5003

    @property
    def playback_socket(self):
        return f'tcp://127.0.0.1:{self.playback_port}'

    local_ip: str = '127.0.0.1'
    mi_rep_port: int = 5557
    muxer_rep_port: int = 5560
    driver_rep_port: int = 5561


    @property
    def mi_rep_socket(self):
        return self.s(self.local_ip, self.device_py_rep_port)

    @property
    def muxer_rep_socket(self):
        return self.s(self.local_ip, self.muxer_rep_port)

    @property
    def driver_rep_socket(self):
        return self.s(self.local_ip, self.driver_rep_port)

    switch1_ip: str = 'c1'
    switch1_token: str = '7ad51e0016e7a9d22f753d5110f76c7d'
    switch2_ip: str = 'c2'
    switch2_token: str = 'bf5a7b77a1ba3761ea63fafd8427b7d6'

    @staticmethod
    def read_config(path: Path):
        j = json.loads(path.read_text(encoding='utf-8'))
        arg_d = dict()
        for field in dataclasses.fields(SoftwareConfig):
            try:
                v = j[field.name]
                match field.type:
                    case Path():
                        arg_d[field.name] = Path(v)
                    case _:
                        arg_d[field.name] = v
            except KeyError:
                pass
        sc = SoftwareConfig(**arg_d)
        return sc

    def write_config(self):
        arg_d = dict()
        for field in dataclasses.fields(SoftwareConfig):
            v = self.__getattribute__(field.name)
            match v:
                case Path():
                    arg_d[field.name] = str(v)
                case _:
                    arg_d[field.name] = v
        SOFTWARE_CONFIG_PATH.parent.mkdir(exist_ok=True, parents=True)
        SOFTWARE_CONFIG_PATH.write_text(json.dumps(arg_d, indent=4), encoding='utf-8')


C = SoftwareConfig()

if SOFTWARE_CONFIG_PATH.exists() and not ISDEV:
    C = SoftwareConfig.read_config(SOFTWARE_CONFIG_PATH)

if __name__ == '__main__':
    print(C)
