import os
import datetime
import time
from common.runtime import load_root_env, as_bool
from smb.SMBConnection import SMBConnection
from utils.datas_processing import pack_elems, agregator, send_data, send_telemetry, save_data, remote_save_data
from utils.jammer_state_flag import is_jammer_active
from core.sig_n_medi_collect import Signal, SignalsArray
from core.multichannelswitcher import MultiChannel

load_root_env(__file__)

debug_flag = as_bool(os.getenv('debug_flag', '0'))
send_to_module_flag = as_bool(os.getenv('send_to_module_flag', '0'))
save_data_flag = as_bool(os.getenv('save_data_flag', '0'))
module_name = os.getenv('module_name')
elems_to_save = os.getenv('elems_to_save')
file_types_to_save = os.getenv('file_types_to_save')
localhost = os.getenv('lochost')
localport = os.getenv('locport')
f_step = [*map(float, os.getenv('f_step_5200').split())]
f_bases = [*map(float, os.getenv('f_bases_5200').split())]
f_roofs = [*map(float, os.getenv('f_roofs_5200').split())]
signal_length = int(os.getenv('signal_length_5200'))
buffer_columns_size = int(os.getenv('buffer_columns_size_5200'))
num_of_thinning_iter = int(os.getenv('num_of_thinning_iter_5200'))
multiply_factor = float(os.getenv('multiply_factor_5200'))
num_for_alarm = int(os.getenv('num_for_alarm_5200'))
c_freq = os.getenv('c_freq_5200', '5200')
path_to_save_medians = os.getenv('path_to_save_medians')
path_to_save_alarms = os.getenv('path_to_save_alarms')
smb_host = os.getenv('smb_host')
smb_port = os.getenv('smb_port')
smb_user = os.getenv('smb_user')
smb_pass = os.getenv('smb_pass')
shared_folder = os.getenv('shared_folder')
the_pc_name = os.getenv('the_pc_name')
remote_pc_name = os.getenv('remote_pc_name')
smb_domain = os.getenv('smb_domain')
freq_endpoint = os.getenv('freq_endpoint')
telemetry_enabled = as_bool(os.getenv('telemetry_enabled', '1'))
telemetry_host = os.getenv('telemetry_host', '127.0.0.1')
telemetry_port = os.getenv('telemetry_port', '5020')
telemetry_endpoint = os.getenv('telemetry_endpoint', 'telemetry')
telemetry_timeout_sec = float(os.getenv('telemetry_timeout_sec', '0.30'))

elems_to_save = elems_to_save.split(',')
file_types_to_save = file_types_to_save.split(',')

tmp_signal = Signal()
tmp_sigs_array = SignalsArray()
multi_channel = MultiChannel(f_step, f_bases, f_roofs)
f = multi_channel.init_f()
multi_channel.fill_DB(
    buffer_columns_size,
    num_of_thinning_iter,
    multiply_factor,
    num_for_alarm,
    c_freq,
)

if debug_flag:
    conn = SMBConnection(smb_user, smb_pass, the_pc_name, remote_pc_name, use_ntlm_v2=True)
    conn.connect(smb_host, 139)
    filelist = conn.listPath(shared_folder, '/')
    print(filelist)


def work(lvl):
    f = multi_channel.get_cur_channel()
    freq = c_freq
    median = tmp_signal.fill_signal(lvl, signal_length)
    packet_ts = tmp_signal.get_last_packet_ts()

    if median:
        try:
            num_chs, circle_buffer = multi_channel.check_f(f)
            cur_channel, sigs_array, sigs_ts_array = tmp_sigs_array.fill_sig_arr(median, packet_ts=packet_ts, num_chs=num_chs)

            if sigs_array:
                print('Значения на {0}: {1}'.format(freq, sigs_array))
                print('Пороги: ', circle_buffer.get_medians())
                alarm = circle_buffer.check_alarm(sigs_array)

                if alarm:
                    print('----ALARM---- ', freq)
                    multi_channel.db_alarms_zeros(circle_buffer)
                elif not is_jammer_active():
                    circle_buffer.update(sigs_array, packet_timestamps=sigs_ts_array)

                if telemetry_enabled:
                    try:
                        max_idx = max(range(len(sigs_array)), key=lambda idx: sigs_array[idx])
                        dbfs_current = float(sigs_array[max_idx])
                        dbfs_threshold = circle_buffer.get_threshold(max_idx)
                        channel_thresholds = circle_buffer.get_thresholds()
                        alarm_channels = circle_buffer.get_last_alarm_channels() if alarm else []

                        send_telemetry(
                            data={
                                'freq': str(freq),
                                'ts': time.time(),
                                'dbfs_current': dbfs_current,
                                'dbfs_threshold': dbfs_threshold,
                                'alarm': bool(alarm),
                                'channel_idx': int(max_idx),
                                'channels_total': int(len(sigs_array)),
                                'channel_values': [float(v) for v in sigs_array],
                                'channel_thresholds': channel_thresholds,
                                'alarm_channels': alarm_channels,
                            },
                            host=telemetry_host,
                            port=telemetry_port,
                            endpoint=telemetry_endpoint,
                            timeout_sec=telemetry_timeout_sec,
                        )
                    except Exception as exc:
                        if debug_flag:
                            print(f'telemetry send failed: {exc}')

                if send_to_module_flag:
                    send_data(agregator(freq, alarm), localhost, localport, freq_endpoint)

                if save_data_flag:
                    if not circle_buffer.check_init() and circle_buffer.current_column - 1 == 0:
                        save_data(path_to_save_medians, freq, 'DateTime', 'ALARM', 'max signal', list(range(num_chs)), list(range(num_chs)))
                    if circle_buffer.check_init():
                        save_data(path_to_save_medians, freq, datetime.datetime.now(), alarm, max(sigs_array), sigs_array, circle_buffer.get_medians())

            if debug_flag:
                single_alarm = circle_buffer.check_single_alarm(median, cur_channel)
                print(cur_channel, single_alarm)
                if single_alarm:
                    data = pack_elems(elems_to_save, file_types_to_save, tmp_signal.get_signal())
                    print('SAVE CURRENT SIGNAL SROCHNO TI MENYA SLISHISH?!?!?!?')
                    try:
                        remote_save_data(conn, data, module_name, freq, shared_folder, path_to_save_alarms)
                    except Exception as e:
                        print(f'Ошибка: {e}')
                else:
                    print('VSE OKI DOKI SIGNAL SOKHRANYAT NE NUZHNO!!!')

            f = multi_channel.change_channel()
        except Exception as e:
            print(str(e))
            print('.', end='')

        tmp_signal.clear()

    return f
