#!/usr/bin/env python3

# standard includes

import _thread
# dbus includes
import json

import dbus
import time

# project includes
import common
from DisplayTask import create_screen_loading_eth_config, create_screen_applying_settings
from util import python_to_dbus


def command_hotspot_turn_on_off(new_state):
    if MonitorTask.proxy is not None:
        # print("CMD_HOTSPOT_TURN_ON_OFF SENT")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.hotspot_enabled(python_to_dbus(new_state))


def command_cloud_turn_on_off(new_state):
    if MonitorTask.proxy is not None:
        # print("CMD_CLOUD_TURN_ON_OFF SENT")
        MonitorTask.is_encoder_blocked = True
        # _thread.start_new(thread_waiting_for_response, ("global", 1))
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.cloud_enabled(python_to_dbus(new_state))    
        MonitorTask.is_encoder_blocked = False
        # proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        # MonitorTask.response = proxy_object.cloud_enabled(python_to_dbus(new_state))


def command_mute_unmute_channel(channel, channel_state):
    # channel state: True for unmuted channel, False for muted channel
    if MonitorTask.proxy is not None:
        # print("CMD_MUTE_UNMUTE_CHANNEL SENT")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.solo_mute_set(python_to_dbus(channel), python_to_dbus(channel_state))


def command_set_freq_gen_frequency(frequency):
    if MonitorTask.proxy is not None:
        # print("CMD_SET_FREQ_GEN_FREQUENCY")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.freq_gen_frequency_set(python_to_dbus(frequency))


def command_set_freq_gen_gain(gain):
    if MonitorTask.proxy is not None:
        # print("CMD_SET_FREQ_GEN_GAIN")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.freq_gen_gain_set(python_to_dbus(gain))


def command_set_pink_noise_gain(gain):
    if MonitorTask.proxy is not None:
        # print("CMD_SET_PINK_NOISE_GAIN")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.pink_noise_gain_set(python_to_dbus(gain))


def command_set_limiter_rms_thres(channel, thres):
    if MonitorTask.proxy is not None:
        # print("CMD_SET_CHANNEL_LIMITER_RMS_THRES")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.solo_lim_rms_thres_set(python_to_dbus(channel),python_to_dbus(thres))


def command_set_limiter_rms_attack(channel, attack):
    if MonitorTask.proxy is not None:
        # print("CMD_SET_CHANNEL_LIMITER_RMS_THRES")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.solo_lim_rms_attack_set(python_to_dbus(channel),python_to_dbus(attack))


def command_set_limiter_rms_release(channel, release):
    if MonitorTask.proxy is not None:
        # print("CMD_SET_CHANNEL_LIMITER_RMS_THRES")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.solo_lim_rms_release_set(python_to_dbus(channel),python_to_dbus(release))


def command_set_limiter_peak_thres(channel, thres):
    if MonitorTask.proxy is not None:
        # print("CMD_SET_CHANNEL_LIMITER_RMS_THRES")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.solo_lim_peak_thres_set(python_to_dbus(channel),python_to_dbus(thres))


def command_set_limiter_peak_release(channel, release):
    if MonitorTask.proxy is not None:
        # print("CMD_SET_CHANNEL_LIMITER_RMS_THRES")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.solo_lim_peak_release_set(python_to_dbus(channel),python_to_dbus(release))


def command_set_xover_lp_freq(channel, freq):
    if MonitorTask.proxy is not None:
        # print("CMD_SET_CHANNEL_XOVER_LP_FREQ")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.solo_xover_lp_freq_set(python_to_dbus(channel),python_to_dbus(freq))


def command_set_xover_lp_type(channel, type):
    if MonitorTask.proxy is not None:
        # print("CMD_SET_CHANNEL_XOVER_LP_TYPE")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.solo_xover_lp_type_set(python_to_dbus(channel),python_to_dbus(type))


def command_set_xover_lp_enable(channel, enabled):
    if MonitorTask.proxy is not None:
        # print("CMD_SET_CHANNEL_XOVER_LP_ENA")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.solo_xover_lp_enable_set(python_to_dbus(channel),python_to_dbus(enabled))


def command_set_xover_hp_freq(channel, freq):
    if MonitorTask.proxy is not None:
        # print("CMD_SET_CHANNEL_XOVER_HP_FREQ")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.solo_xover_hp_freq_set(python_to_dbus(channel),python_to_dbus(freq))


def command_set_xover_hp_type(channel, type):
    if MonitorTask.proxy is not None:
        # print("CMD_SET_CHANNEL_XOVER_HP_TYPE")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.solo_xover_hp_type_set(python_to_dbus(channel),python_to_dbus(type))


def command_set_xover_hp_enable(channel, enabled):
    if MonitorTask.proxy is not None:
        # print("CMD_SET_CHANNEL_XOVER_HP_ENA")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.solo_xover_hp_enable_set(python_to_dbus(channel),python_to_dbus(enabled))


def command_set_peq_q(channel, peq, q):
    if MonitorTask.proxy is not None:
        # print("CMD_SET_CHANNEL_PEQ_Q")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.solo_peq_q_set(python_to_dbus(channel), python_to_dbus(peq), python_to_dbus(q))


def command_set_peq_gain(channel, peq, gain):
    if MonitorTask.proxy is not None:
        # print("CMD_SET_CHANNEL_PEQ_GAIN")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.solo_peq_gain_set(python_to_dbus(channel), python_to_dbus(peq), python_to_dbus(gain))


def command_set_peq_freq(channel, peq, freq):
    if MonitorTask.proxy is not None:
        # print("CMD_SET_CHANNEL_PEQ_FREQ")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.solo_peq_freq_set(python_to_dbus(channel), python_to_dbus(peq), python_to_dbus(freq))


def command_set_peq_type(channel, peq, type):
    if MonitorTask.proxy is not None:
        # print("CMD_SET_CHANNEL_PEQ_TYPE")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.solo_peq_type_set(python_to_dbus(channel), python_to_dbus(peq), python_to_dbus(type))


def command_set_peq_enable(channel, peq, enabled):
    if MonitorTask.proxy is not None:
        # print("CMD_SET_CHANNEL_PEQ_ENA")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.solo_peq_enable_set(python_to_dbus(channel), python_to_dbus(peq), python_to_dbus(enabled))


def command_set_channel_delay(channel, delay):
    if MonitorTask.proxy is not None:
        # print("CMD_SET_CHANNEL_GAIN SENT")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.solo_delay_value_set(python_to_dbus(channel), python_to_dbus(delay))


def command_set_channel_delay_enable(channel, enable):
    if MonitorTask.proxy is not None:
        # print("CMD_SET_CHANNEL_GAIN SENT")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.solo_delay_enable_set(python_to_dbus(channel), python_to_dbus(enable))


def command_set_channel_gain(channel, gain):
    if MonitorTask.proxy is not None:
        # print("CMD_SET_CHANNEL_GAIN SENT")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.solo_gain_set(python_to_dbus(channel), python_to_dbus(gain))


def command_set_channel_source(channel, source):
    if MonitorTask.proxy is not None:
        # print("CMD_SET_CHANNEL_SOURCE SENT")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.solo_channel_source_pri_set(python_to_dbus(channel), python_to_dbus(source))


def command_set_channel_source_mixer(channel, source, gain):
    if MonitorTask.proxy is not None:
        # print("CMD_SET_CHANNEL_SOURCE_MIXER_GAIN")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.solo_channel_source_mixer_set(python_to_dbus(channel), python_to_dbus(source), python_to_dbus(gain))


def command_set_global_preset(folder, file):
    path = str(folder) + "/" + str(file)
    if MonitorTask.proxy is not None:
        # print("CMD_SET_GLOBAL_PRESET SENT")
        MonitorTask.is_encoder_blocked = True
        _thread.start_new(thread_waiting_for_response, ("global", 1))
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.global_preset_file_set(python_to_dbus(path))
        MonitorTask.is_encoder_blocked = False
        return MonitorTask.response


def command_set_speaker_preset(channel, folder, file):
    path = str(folder) + "/" + str(file)
    if MonitorTask.proxy is not None:
        # print("CMD_SET_SPEAKER_PRESET SENT")
        MonitorTask.is_encoder_blocked = True
        _thread.start_new(thread_waiting_for_response, ("speaker", 1))
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.speaker_preset_file_set(python_to_dbus(path), python_to_dbus(channel))
        MonitorTask.is_encoder_blocked = False
        return MonitorTask.response

def command_set_all_speaker_preset(folder, file):
    path = str(folder) + "/" + str(file)
    if MonitorTask.proxy is not None:
        # print("CMD_SET_SPEAKER_PRESET SENT")
        MonitorTask.is_encoder_blocked = True
        _thread.start_new(thread_waiting_for_response, ("speaker", 1))
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.all_speaker_preset_file_set(python_to_dbus(path))
        MonitorTask.is_encoder_blocked = False
        return MonitorTask.response

def command_set_channel_name(channel, name):
    if MonitorTask.proxy is not None:
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.solo_channel_name_set(python_to_dbus(channel), python_to_dbus(name))
        return MonitorTask.response

def command_set_dhcp_ethernet():
    if MonitorTask.proxy is not None:
        # print("DHCP ETHERNET COMMAND SENT")
        MonitorTask.is_encoder_blocked = True
        _thread.start_new(thread_waiting_for_response, ("dhcp", 1))
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.eth_dhcp_config()
        MonitorTask.is_encoder_blocked = False
        return MonitorTask.response


def command_set_static_ethernet(ip, net_mask, gw):
    if MonitorTask.proxy is not None:
        # print("STATIC ETHERNET COMMAND SENT", ip, net_mask)
        config = json.dumps({"ip_addr": ip, "netmask": net_mask, "gateway": gw})
        MonitorTask.is_encoder_blocked = True
        _thread.start_new(thread_waiting_for_response, ("static", 1))
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.eth_static_config(str(config))
        MonitorTask.is_encoder_blocked = False
        return MonitorTask.response


def command_get_data_home_page_status():
    if MonitorTask.proxy is not None:
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.data_home_page_status_get()
        return MonitorTask.response


def command_get_solo_mixer_all_gain(channel):
    if MonitorTask.proxy is not None:
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.solo_channel_source_mixer_all_get(python_to_dbus(channel))
        return MonitorTask.response

def command_get_data_audio_siggen():
    if MonitorTask.proxy is not None:
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.data_audio_siggen_get()
        return MonitorTask.response


def command_get_data_audio_limiter(channel):
    if MonitorTask.proxy is not None:
        # print("GET DATA AUDIO LIMITER SCREEN")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.data_audio_limiter_get(python_to_dbus(channel))
        return MonitorTask.response


def command_get_data_audio_xover(channel):
    if MonitorTask.proxy is not None:
        # print("GET DATA AUDIO XOVER SCREEN")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.data_audio_xover_get(python_to_dbus(channel))
        return MonitorTask.response


def command_get_data_audio_peq(channel):
    if MonitorTask.proxy is not None:
        # print("GET DATA AUDIO PEQ SCREEN")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.data_audio_peq_get(python_to_dbus(channel))
        return MonitorTask.response


def command_get_data_audio_delay():
    if MonitorTask.proxy is not None:
        # print("GET DATA AUDIO DELAY SCREEN")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.data_audio_delay_get()
        return MonitorTask.response


def command_get_data_audio_gain():
    if MonitorTask.proxy is not None:
        # print("GET DATA AUDIO GAIN SCREEN")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.data_audio_gain_get()
        return MonitorTask.response


def command_get_data_audio_source():
    if MonitorTask.proxy is not None:
        # print("GET DATA AUDIO SOURCE SCREEN")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.data_audio_source_get()
        return MonitorTask.response


def command_get_data_global_presets_folder():
    if MonitorTask.proxy is not None:
        # print("GET DATA GLOBAL PRESETS FOLDER SCREEN")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.global_preset_folder_names_get()
        return MonitorTask.response


def command_get_data_global_presets_file(folder_name):
    if MonitorTask.proxy is not None:
        # print("GET DATA GLOBAL PRESETS FILE SCREEN")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.global_preset_file_names_get(folder_name)
        return MonitorTask.response

def command_get_data_speaker_presets_list():
    if MonitorTask.proxy is not None:
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.speaker_preset_list_names_get()
        return MonitorTask.response

def command_get_data_speaker_presets_folder():
    if MonitorTask.proxy is not None:
        # print("GET DATA SPEAKER PRESETS FOLDER SCREEN")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.speaker_preset_folder_names_get()
        return MonitorTask.response

def command_get_data_speaker_presets_file(folder_name):
    if MonitorTask.proxy is not None:
        # print("GET DATA SPEAKER PRESETS FILE SCREEN")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.speaker_preset_file_names_get(folder_name)
        return MonitorTask.response

def command_get_data_all_speaker_presets_folder():
    if MonitorTask.proxy is not None:
        # print("GET DATA SPEAKER PRESETS FOLDER SCREEN")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.all_speaker_preset_folder_names_get()
        return MonitorTask.response


def command_get_data_all_speaker_presets_file(folder_name):
    if MonitorTask.proxy is not None:
        # print("GET DATA SPEAKER PRESETS FILE SCREEN")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.all_speaker_preset_file_names_get(folder_name)
        return MonitorTask.response

def command_get_data_hotspot():
    if MonitorTask.proxy is not None:
        # print("GET DATA HOTSPOT SCREEN")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.data_hotspot_get()
        return MonitorTask.response


def command_get_data_cloud():
    if MonitorTask.proxy is not None:
        # print("GET DATA CLOUD SCREEN")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.data_cloud_get()
        return MonitorTask.response


def command_get_data_network():
    if MonitorTask.proxy is not None:
        # print("GET DATA NETWORK SCREEN")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.data_network_get()
        return MonitorTask.response


def command_get_data_about():
    if MonitorTask.proxy is not None:
        # print("GET DATA ABOUT SCREEN")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.data_about_get()
        return MonitorTask.response


def command_start_readback():
    if MonitorTask.proxy is not None:
        # print("START READBACK")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.start_peak_readback()
        return MonitorTask.response


def command_stop_readback():
    if MonitorTask.proxy is not None:
        # print("STOP READBACK")
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.stop_peak_readback()
        return MonitorTask.response

def command_get_front_lock():
    if MonitorTask.proxy is not None:
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.front_lock_get()
        return MonitorTask.response
    
def command_reset_locate():
    if MonitorTask.proxy is not None:
        proxy_object = MonitorTask.bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
        MonitorTask.response = proxy_object.locate_reset()
        return MonitorTask.response

def thread_waiting_for_response(thread_name, delay):
    try:
        if thread_name == "dhcp" or thread_name == "static":
            create_screen_loading_eth_config()
        elif thread_name == "global" or thread_name == "speaker":
            create_screen_applying_settings()
    except Exception:
        import traceback
        print(traceback.format_exc())


class MonitorTask:
    bus = dbus.SystemBus()
    iface = None
    response = False
    is_encoder_blocked = False

    try:
        proxy = bus.get_object(common.SERVICE_BUS, common.SERVICE_OBJECT_PATH)
    except dbus.DBusException as e:
        # There are actually two exceptions thrown:
        # 1: org.freedesktop.DBus.Error.NameHasNoOwner
        #   (when the name is not registered by any running process)
        # 2: org.freedesktop.DBus.Error.ServiceUnknown
        #   (during auto-activation since there is no .service file)
        # TODO figure out how to suppress the activation attempt
        # also, there *has* to be a better way of managing exceptions
        if e._dbus_error_name != 'org.freedesktop.DBus.Error.ServiceUnknown':
            raise
        if e.__context__._dbus_error_name != 'org.freedesktop.DBus.Error.NameHasNoOwner':
            raise
        print('client: No one can hear me!!')
