# /usr/bin/python

import sys
import base64
import json
from time import sleep
from libs.common import api_call
from libs.adding.user_generator import create_users
from libs.adding.device_generator import create_devices
from libs.adding.agents_generator import create_agents, queue_populate
from libs.config import CONFIG


def create_basic_auth() -> None:
    auth_string = f"{CONFIG['ws_user']}:{CONFIG['ws_pass']}"
    auth_bytes = auth_string.encode("ascii")
    CONFIG["auth"] = base64.b64encode(auth_bytes)


def create_and_upload_users():
    users = create_users(
        CONFIG["user_tag"], 
        CONFIG["line_type"], 
        CONFIG["first_exten"], 
        CONFIG["password"], 
        CONFIG["count"], 
        CONFIG["context"], 
        CONFIG["mds"], 
        CONFIG["user_tag_increment"], 
        CONFIG["user_tag_first"]
    )
    return upload_users(users)


def live_reload_configuration(reload_conf: bool) -> None:
    print(f"Switch the live reload configuration to {reload_conf}")
    method = "PUT"
    url = f"{CONFIG['url_prefix']}/configuration/live_reload"
    headers = {
        "Content-Type": "application/json",
        "Authorization": f"Basic {CONFIG['auth']}"
    }
    data= {
        "enabled": reload_conf
    }
    payload = json.dumps(data)
    api_call(method, url, headers, payload)


def upload_users(users: list):
    print("Uploading batch of users...")
    method = "POST"
    url = f"{CONFIG['url_prefix']}/users/import"
    headers = {
        "Content-Type": "text/csv; charset=utf-8",
        "Authorization": f"Basic {CONFIG['auth']}"
    }
    payload = users
    response = api_call(method, url, headers, payload)

    if "is outside of range for context" in response.text:
        print("ERROR: The range of extensions is outside of the context range. Please check your configuration (first_exten and count).")
        sys.exit(1)
    elif "User already exists" in response.text:
        print("ERROR: A user already exists. Please check your configuration (first_exten and count).")
        print("Also, you probably want to delete all users before creating new ones.('delete_everything=true' in .env)")
        sys.exit(1)
    else:
        return response



def extract_line_ids(user_api_response) -> None:
    response_json = user_api_response.json()
    for user in response_json["created"]:
        CONFIG["line_ids"].append(user["line_id"])


def create_and_upload_devices():
    devices = create_devices(
        CONFIG["first_exten"], 
        CONFIG["count"], 
        CONFIG["plugin_config"]
    )
    return upload_devices(devices)


def upload_devices(devices):
    device_api_responses = []
    for device in devices:
        device_api_response = upload_device(device)
        response_json = device_api_response.json()
        device_api_responses.append(response_json)
        sleep(1)

    return device_api_responses


def upload_device(device):
    print(f"Uploading device: {device}")
    method = "POST"
    url = f"{CONFIG['url_prefix']}/devices"
    headers = {
        "Content-Type": "application/json",
        "Accept": "application/json"
    }
    payload = json.dumps(device)
    response = api_call(method, url, headers, payload)
    if response.status_code == 400:
        if "Plugin was not found" in response.text:
            print("ERROR: The plugin was not found. Please add plugin to XiVO and try again.")
            sys.exit(1)
    return response


def extract_device_ids(device_api_responses) -> None:
    for device in device_api_responses:
        CONFIG["device_ids"].append(device["id"])


def associate_user_lines_with_devices() -> None:
    for line_id, device_id in zip(CONFIG["line_ids"], CONFIG["device_ids"]):
        upload_association(line_id, device_id)


def upload_association(line_id, device_id):
    print(f"Assotiating device: {device_id} with line: {line_id}")
    method = "PUT"
    url = f"{CONFIG['url_prefix']}/lines/{line_id}/devices/{device_id}"
    return api_call(method, url)


def add_config() -> None:
    create_basic_auth()
    if CONFIG["create_users"] == "true":
        if (CONFIG["line_type"] == 'webrtc'):
            create_and_upload_users()
        else:
            live_reload_configuration(False)
            user_api_response = create_and_upload_users()
            extract_line_ids(user_api_response)
            device_api_responses = create_and_upload_devices()
            extract_device_ids(device_api_responses)
            associate_user_lines_with_devices()
            live_reload_configuration(True)
    if CONFIG["create_agents"] == "true":
        create_agents()
    if CONFIG["populate_queue"] == "true":
        queue_populate()


