#include "system/app_core.h"
#include "server/server_core.h"
#include "server/audio_server.h"
#include "app_config.h"
#include "btstack/avctp_user.h"
#include "btstack/le/ble_api.h"
#include "btstack/btstack_task.h"
#include "btctrler/btctrler_task.h"
#include "btcontroller_modules.h"
#include "bt_common.h"
#include "a2dp_media_codec.h"
#include "btstack/bluetooth.h"
#include "btstack/btstack_error.h"
#include "event/bt_event.h"
#include "app_power_manage.h"
#include "syscfg/syscfg_id.h"
#include "wifi/wifi_connect.h"
#include "asm/rf_coexistence_config.h"

#include "wbcp.h"

#define LOG_TAG_CONST        BT
#define LOG_TAG             "[BT]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
#define LOG_DUMP_ENABLE
#define LOG_CLI_ENABLE
#include "debug.h"

#define TIMEOUT_CONN_TIME         30 //超时断开之后回连的时间s
#define POWERON_AUTO_CONN_TIME    18  //开机去回连的时间,要取6的倍数
#define BT_INBAND_RINGTONE        1

extern u8 get_esco_coder_busy_flag(void);
extern void get_remote_device_info_from_vm(void);
extern bool get_esco_busy_flag(void);
extern void bredr_close_all_scan(void);
extern void __set_simple_pair_flag(bool flag);
extern void low_power_hw_unsleep_lock(void);
extern void low_power_hw_unsleep_unlock(void);

struct app_bt_opr {
    u8 enable    : 1;
    int auto_connection_counter;
    u8 auto_connection_addr[6];
    u16 auto_connection_timer;
    u16 poweroff_timer_id;
};

static struct app_bt_opr app_bt_hdl;
#define __this 	(&app_bt_hdl)

#define SBC_FILTER_TIME_MS			2000	//后台音频过滤时间ms
#define SBC_ZERO_TIME_MS			500		//静音多长时间认为已经退出
#define NO_SBC_TIME_MS				100		//无音频时间ms

__attribute__((weak)) void del_bt_emitter_fix_timer()
{
    ;
}

/*开关可发现可连接的函数接口*/
static void bt_wait_phone_connect_control(u8 enable)
{
    if (!__this->enable && enable) {
        return;
    }

    if (enable) {
        log_info("is_1t2_connection:%d \t total_conn_dev:%d", is_1t2_connection(), get_total_connect_dev());
        if (is_1t2_connection()) {
            /*达到最大连接数，可发现(0)可连接(0)*/
            user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_DISABLE, 0, NULL);
            user_send_cmd_prepare(USER_CTRL_WRITE_CONN_DISABLE, 0, NULL);
        } else {
            if (get_total_connect_dev() == 1) {
                /*支持连接2台，只连接一台的情况下，可发现(0)可连接(1)*/
                user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_DISABLE, 0, NULL);
                user_send_cmd_prepare(USER_CTRL_WRITE_CONN_ENABLE, 0, NULL);
            } else {
                /*可发现(1)可连接(1)*/
                user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_ENABLE, 0, NULL);
                user_send_cmd_prepare(USER_CTRL_WRITE_CONN_ENABLE, 0, NULL);
            }
        }
    } else {
        user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_DISABLE, 0, NULL);
        user_send_cmd_prepare(USER_CTRL_WRITE_CONN_DISABLE, 0, NULL);
    }
}

static void bt_init_ok_search_index(void)
{
    if (!__this->auto_connection_counter && get_current_poweron_memory_search_index(__this->auto_connection_addr)) {
        log_info("bt_wait_connect_and_phone_connect_switch");
        clear_current_poweron_memory_search_index(1);
#if (TCFG_BD_NUM == 2)
        clear_current_poweron_memory_search_index(1);
#endif
        __this->auto_connection_counter = POWERON_AUTO_CONN_TIME * 1000; //8000ms
    }
}

static int bt_wait_connect_and_phone_connect_switch(void *p)
{
    int ret = 0;
    int timeout = 0;

    log_info("connect_switch: %d, %d", (int)p, __this->auto_connection_counter);

    if (!__this->enable) {
        return 0;
    }

    __this->auto_connection_timer = 0;

    if (__this->auto_connection_counter <= 0) {
        __this->auto_connection_counter = 0;
        user_send_cmd_prepare(USER_CTRL_PAGE_CANCEL, 0, NULL);

        if (get_current_poweron_memory_search_index(NULL)) {
            bt_init_ok_search_index();
            return bt_wait_connect_and_phone_connect_switch(0);
        } else {
            bt_wait_phone_connect_control(1);
            return 0;
        }
    }
    /* log_info(">>>phone_connect_switch=%d",__this->auto_connection_counter ); */
    if (!p) {
        if (__this->auto_connection_counter) {
            timeout = 4000;
            bt_wait_phone_connect_control(0);
            switch_rf_coexistence_config_table(7);
            user_send_cmd_prepare(USER_CTRL_START_CONNEC_VIA_ADDR, 6, __this->auto_connection_addr);
            ret = 1;
        }
    } else {
        timeout = 2000;
        user_send_cmd_prepare(USER_CTRL_PAGE_CANCEL, 0, NULL);
        bt_wait_phone_connect_control(1);
        switch_rf_coexistence_config_table(0);
    }

    if (__this->auto_connection_counter) {
        __this->auto_connection_counter -= timeout;
        log_info("do=%d", __this->auto_connection_counter);
    }

    __this->auto_connection_timer = sys_timeout_add((void *)(!(int)p),
                                    (void (*)(void *))bt_wait_connect_and_phone_connect_switch, timeout);

    return ret;
}

#define SYS_BT_EVENT_TYPE_DECODE_STATUS (('D' << 24) | ('E' << 16) | ('C' << 8) | '\0')

static void bt_read_remote_name(u8 status, u8 *addr, u8 *name)
{
    if (status) {
        log_error("remote_name fail ");
    } else {
        log_info("remote_name : %s ", name);
    }

    put_buf(addr, 6);
}

static void bt_dut_api(u8 value)
{
    log_info("bt in dut");
    bredr_close_all_scan();
}

static void bredr_handle_register(void)
{
    ///样机进入dut被测试仪器链接上回调
    bt_dut_test_handle_register(bt_dut_api);

    ///获取远端设备蓝牙名字回调
    read_remote_name_handle_register(bt_read_remote_name);
}

static void bt_function_select_init(void)
{
    __set_user_ctrl_conn_num(TCFG_BD_NUM);
    __set_support_msbc_flag(1);
    __bt_set_update_battery_time(0);
    __set_page_timeout_value(8000); /*回连搜索时间长度设置,可使用该函数注册使用，ms单位,u16*/
    __set_super_timeout_value(8000); /*回连时超时参数设置。ms单位。做主机有效*/

#if (TCFG_BD_NUM == 2)
    ////设置开机回链的设备个数
    __set_auto_conn_device_num(2);
#endif

    __set_simple_pair_flag(1); //是否打开简易配对功能，打开后不需要输入pincode
    ////设置蓝牙加密的level
    //io_capabilities ; /*0: Display only 1: Display YesNo 2: KeyboardOnly 3: NoInputNoOutput*/
    //authentication_requirements: 0:not protect  1 :protect
    __set_simple_pair_param(3, 0, 2);

    /* __set_disable_hfp_ag_flag(1); */

#if TCFG_USER_BLE_ENABLE
    u8 tmp_ble_addr[6];
    extern const u8 *bt_get_mac_addr(void);
    extern void lib_make_ble_address(u8 * ble_address, u8 * edr_address);
    extern int le_controller_set_mac(void *addr);
    lib_make_ble_address(tmp_ble_addr, (u8 *)bt_get_mac_addr());
    le_controller_set_mac((void *)tmp_ble_addr);
    log_info("\n-----edr + ble 's address-----");
    put_buf((void *)bt_get_mac_addr(), 6);
    put_buf((void *)tmp_ble_addr, 6);
#endif
}

void bt_ble_module_init(void)
{
    bt_function_select_init();
    bredr_handle_register();
    btstack_init();
}

void bt_connection_enable(void)
{
    if (__this->enable) {
        return;
    }
    if (__this->poweroff_timer_id) {
        sys_timeout_del(__this->poweroff_timer_id);
        __this->poweroff_timer_id = 0;
    }
#ifdef CONFIG_LOW_POWER_ENABLE
    low_power_hw_unsleep_lock();
    btctrler_task_init_bredr();
    low_power_hw_unsleep_unlock();
#endif
    __this->enable = 1;
    __this->auto_connection_counter = 0;
    get_remote_device_info_from_vm();
    bt_init_ok_search_index();

    bt_wait_connect_and_phone_connect_switch(0);
}

static void bt_power_off(void *p)
{
    if (is_1t2_connection() || get_total_connect_dev() > 0) {
        user_send_cmd_prepare(USER_CTRL_PAGE_CANCEL, 0, NULL);
        user_send_cmd_prepare(USER_CTRL_CONNECTION_CANCEL, 0, NULL);
        user_send_cmd_prepare(USER_CTRL_DISCONNECTION_HCI, 0, NULL);
        __this->poweroff_timer_id = sys_timeout_add(NULL, bt_power_off, 100);
        return;
    }
    __this->poweroff_timer_id = 0;
    user_send_cmd_prepare(USER_CTRL_POWER_OFF, 0, NULL);
#ifdef CONFIG_LOW_POWER_ENABLE
    os_time_dly(50);
    low_power_hw_unsleep_lock();
    btctrler_task_close_bredr();
    low_power_hw_unsleep_unlock();
#endif
}

void bt_delete_power_off_timer(void)
{
    if (__this->poweroff_timer_id) {
        sys_timeout_del(__this->poweroff_timer_id);
        __this->poweroff_timer_id = 0;
    }
}

//关闭蓝牙
void bt_connection_disable(void)
{
    if (!__this->enable) {
        return;
    }

    __this->enable = 0;
    if (__this->auto_connection_timer) {
        sys_timer_del(__this->auto_connection_timer);
        __this->auto_connection_timer = 0;
    }
    switch_rf_coexistence_config_table(0);
    bt_wait_phone_connect_control(0);
    user_send_cmd_prepare(USER_CTRL_PAGE_CANCEL, 0, NULL);
    user_send_cmd_prepare(USER_CTRL_CONNECTION_CANCEL, 0, NULL);
    user_send_cmd_prepare(USER_CTRL_DISCONNECTION_HCI, 0, NULL);

    if (!__this->poweroff_timer_id) {
        __this->poweroff_timer_id = sys_timeout_add(NULL, bt_power_off, 500);
    }
    /* user_send_cmd_prepare(USER_CTRL_INQUIRY_CANCEL, 0, NULL); */
}

/*
 * 对应原来的状态处理函数，连接，电话状态等
 */
static int bt_connction_status_event_handler(struct bt_event *bt)
{
    struct intent it = {0};
    log_info("-+-bt_connction_status_event_handler 0x%x", bt->event);

    switch (bt->event) {
    case BT_STATUS_INIT_OK:
        /*
         * 蓝牙初始化完成
         */
        log_info("===================BT_STATUS_INIT_OK");
#ifdef CONFIG_LOW_POWER_ENABLE
        btctrler_task_close_bredr();
#endif
        break;
    case BT_STATUS_START_CONNECTED:
        log_info(" BT_STATUS_START_CONNECTED");
        break;
    case BT_STATUS_ENCRY_COMPLETE:
        log_info(" BT_STATUS_ENCRY_COMPLETE");
        break;
    case BT_STATUS_SECOND_CONNECTED:
        log_info("BT_STATUS_CONNECTED");
        clear_current_poweron_memory_search_index(0);
    case BT_STATUS_FIRST_CONNECTED:
        log_info("BT_STATUS_FIRST_CONNECTED");
        sys_power_auto_shutdown_pause();
#if (TCFG_BD_NUM == 2)
        if (get_current_poweron_memory_search_index(NULL) == 0) {
            bt_wait_phone_connect_control(1);
        }
#endif
        break;
    case BT_STATUS_FIRST_DISCONNECT:
    case BT_STATUS_SECOND_DISCONNECT:
        log_info("BT_STATUS_DISCONNECT");
        /* __this->call_flag = 0; */
        /* __this->media_play_flag = 0; */
#if TCFG_BD_NUM == 2
        if (get_total_connect_dev() == 0)  {
#endif
            sys_power_auto_shutdown_resume();
            switch_rf_coexistence_config_table(0);
#if TCFG_BD_NUM == 2
        }
#endif
        break;
    //phone status deal
    case BT_STATUS_PHONE_INCOME:
        log_info("BT_STATUS_PHONE_INCOME");
        break;
    case BT_STATUS_PHONE_OUT:
        log_info("BT_STATUS_PHONE_OUT");
        break;
    case BT_STATUS_PHONE_ACTIVE:
        log_info("BT_STATUS_PHONE_ACTIVE");
        break;
    case BT_STATUS_PHONE_HANGUP:
        log_info("phone_hangup");
        break;
    case BT_STATUS_PHONE_NUMBER:
        log_info("BT_STATUS_PHONE_NUMBER");
        break;
    case BT_STATUS_INBAND_RINGTONE:
        log_info("BT_STATUS_INBAND_RINGTONE");
        break;
    case BT_STATUS_BEGIN_AUTO_CON:
        log_info("BT_STATUS_BEGIN_AUTO_CON");
        break;
    case BT_STATUS_A2DP_MEDIA_START:
        log_info(" BT_STATUS_A2DP_MEDIA_START");
        break;
    case BT_STATUS_A2DP_MEDIA_STOP:
        log_info(" BT_STATUS_A2DP_MEDIA_STOP");
        break;
    case BT_STATUS_SCO_STATUS_CHANGE:
        log_info(" BT_STATUS_SCO_STATUS_CHANGE len:%d ,type:%d", (bt->value >> 16), (bt->value & 0x0000ffff));
        break;
    case BT_STATUS_CALL_VOL_CHANGE:
        log_info(" BT_STATUS_CALL_VOL_CHANGE %d", bt->value);
        break;
    case BT_STATUS_SNIFF_STATE_UPDATE:
        log_info(" BT_STATUS_SNIFF_STATE_UPDATE %d", bt->value);    //0退出SNIFF
        break;
    case BT_STATUS_LAST_CALL_TYPE_CHANGE:
        log_info("BT_STATUS_LAST_CALL_TYPE_CHANGE:%d", bt->value);
        break;
    case BT_STATUS_CONN_A2DP_CH:
        break;
    case BT_STATUS_CONN_HFP_CH:
        if ((!is_1t2_connection()) && (get_current_poweron_memory_search_index(NULL))) { //回连下一个device
            if (get_esco_coder_busy_flag()) {
                clear_current_poweron_memory_search_index(0);
            } else {
                user_send_cmd_prepare(USER_CTRL_START_CONNECTION, 0, NULL);
            }
        }
        break;
    case BT_STATUS_PHONE_MANUFACTURER:
        log_info("BT_STATUS_PHONE_MANUFACTURER:%d", bt->value);
        break;
    case BT_STATUS_VOICE_RECOGNITION:
        log_info(" BT_STATUS_VOICE_RECOGNITION:%d", bt->value);
        break;
    case BT_STATUS_AVRCP_INCOME_OPID:
        break;
    case BT_STATUS_RECONN_OR_CONN:
        log_info(" BT_STATUS_RECONN_OR_CONN");
        del_bt_emitter_fix_timer();
        break;
    default:
        log_info(" BT STATUS DEFAULT");
        break;
    }

    return 0;
}

static u8 bt_hci_event_filter(struct bt_event *bt)
{
    if (bt->event == HCI_EVENT_VENDOR_REMOTE_TEST) {
        if (0 == bt->value) {
            set_remote_test_flag(0);
            /* log_debug("clear_test_box_flag"); */
            return 0;
        } else {
        }
    }

    if ((bt->event != HCI_EVENT_CONNECTION_COMPLETE) ||
        ((bt->event == HCI_EVENT_CONNECTION_COMPLETE) && (bt->value != ERROR_CODE_SUCCESS))) {
        if (get_remote_test_flag() \
            && !(HCI_EVENT_DISCONNECTION_COMPLETE == bt->event) \
            && !(HCI_EVENT_VENDOR_REMOTE_TEST == bt->event)) {
            log_info("cpu reset");
            /* cpu_reset(); */
        }
    }

    return 1;
}

static void bt_send_pair(u8 en)
{
    user_send_cmd_prepare(USER_CTRL_PAIR, 1, &en);
}

static int bt_hci_event_handler(struct bt_event *bt)
{
    //对应原来的蓝牙连接上断开处理函数  ,bt->value=reason
    log_info("+-+bt_hci_event_handler reason 0x%x", bt->event);

    if (bt_hci_event_filter(bt) == 0) {
        return 0;
    }

    switch (bt->event) {
    case HCI_EVENT_INQUIRY_COMPLETE:
        log_info(" HCI_EVENT_INQUIRY_COMPLETE");
        break;
    case HCI_EVENT_IO_CAPABILITY_REQUEST:
        log_info(" HCI_EVENT_IO_CAPABILITY_REQUEST");
        break;
    case HCI_EVENT_USER_CONFIRMATION_REQUEST:
        log_info(" HCI_EVENT_USER_CONFIRMATION_REQUEST");
        ///<可通过按键来确认是否配对 1：配对   0：取消
        bt_send_pair(1);
        break;
    case HCI_EVENT_USER_PASSKEY_REQUEST:
        log_info(" HCI_EVENT_USER_PASSKEY_REQUEST");
        ///<可以开始输入6位passkey
        break;
    case HCI_EVENT_USER_PRESSKEY_NOTIFICATION:
        log_info(" HCI_EVENT_USER_PRESSKEY_NOTIFICATION %x", bt->value);
        ///<可用于显示输入passkey位置 value 0:start  1:enrer  2:earse   3:clear  4:complete
        break;
    case HCI_EVENT_PIN_CODE_REQUEST :
        log_info("HCI_EVENT_PIN_CODE_REQUEST");
        bt_send_pair(1);
        break;
    case HCI_EVENT_VENDOR_NO_RECONN_ADDR :
        log_info("HCI_EVENT_VENDOR_NO_RECONN_ADDR");
    case HCI_EVENT_DISCONNECTION_COMPLETE :
        log_info("HCI_EVENT_DISCONNECTION_COMPLETE");
#if (TCFG_BD_NUM == 2)
        if ((bt->value == ERROR_CODE_CONNECTION_REJECTED_DUE_TO_UNACCEPTABLE_BD_ADDR) ||
            (bt->value == ERROR_CODE_CONNECTION_ACCEPT_TIMEOUT_EXCEEDED)) {
            /*
             *连接接受超时
             *如果支持1t2，可以选择继续回连下一台，除非已经回连完毕
             */
            if (get_current_poweron_memory_search_index(NULL)) {
                user_send_cmd_prepare(USER_CTRL_START_CONNECTION, 0, NULL);
                break;
            }
        }
#endif

#ifndef CONFIG_DUI_SDK_ENABLE
        bt_wait_phone_connect_control(1);
#else
        user_send_cmd_prepare(USER_CTRL_WRITE_CONN_ENABLE, 0, NULL);
#endif
        break;
    case BTSTACK_EVENT_HCI_CONNECTIONS_DELETE:
    case HCI_EVENT_CONNECTION_COMPLETE:
        log_info("HCI_EVENT_CONNECTION_COMPLETE : 0x%x", bt->value);
        switch (bt->value) {
        case ERROR_CODE_SUCCESS :
            log_info("ERROR_CODE_SUCCESS");
            if (__this->auto_connection_timer) {
                sys_timeout_del(__this->auto_connection_timer);
                __this->auto_connection_timer = 0;
            }
            __this->auto_connection_counter = 0;
            bt_wait_phone_connect_control(0);
            user_send_cmd_prepare(USER_CTRL_ALL_SNIFF_EXIT, 0, NULL);
            break;

        case ERROR_CODE_REMOTE_USER_TERMINATED_CONNECTION:
        case ERROR_CODE_PIN_OR_KEY_MISSING:
            log_info(" ERROR_CODE_PIN_OR_KEY_MISSING");
        case ERROR_CODE_SYNCHRONOUS_CONNECTION_LIMIT_TO_A_DEVICE_EXCEEDED :
        case ERROR_CODE_CONNECTION_REJECTED_DUE_TO_LIMITED_RESOURCES:
        case ERROR_CODE_CONNECTION_REJECTED_DUE_TO_UNACCEPTABLE_BD_ADDR:
        case ERROR_CODE_CONNECTION_ACCEPT_TIMEOUT_EXCEEDED  :
        case ERROR_CODE_CONNECTION_TERMINATED_BY_LOCAL_HOST :
        case ERROR_CODE_AUTHENTICATION_FAILURE :
        case CUSTOM_BB_AUTO_CANCEL_PAGE:
#if (TCFG_BD_NUM == 2)
            if ((bt->value == ERROR_CODE_CONNECTION_REJECTED_DUE_TO_UNACCEPTABLE_BD_ADDR) ||
                (bt->value == ERROR_CODE_CONNECTION_ACCEPT_TIMEOUT_EXCEEDED)) {
                /*
                 *连接接受超时
                 *如果支持1t2，可以选择继续回连下一台，除非已经回连完毕
                 */
                if (get_current_poweron_memory_search_index(NULL)) {
                    user_send_cmd_prepare(USER_CTRL_START_CONNECTION, 0, NULL);
                    break;
                }
            }
#endif
            bt_wait_phone_connect_control(1);
            break;
        case ERROR_CODE_PAGE_TIMEOUT:
            log_info(" ERROR_CODE_PAGE_TIMEOUT");
            if (__this->auto_connection_timer) {
                sys_timer_del(__this->auto_connection_timer);
                __this->auto_connection_timer = 0;
            }
#if (TCFG_BD_NUM == 2)
            if (get_current_poweron_memory_search_index(NULL)) {
                user_send_cmd_prepare(USER_CTRL_START_CONNECTION, 0, NULL);
                break;
            }
#endif
            bt_wait_phone_connect_control(1);
            break;
        case ERROR_CODE_CONNECTION_TIMEOUT:
            log_info(" ERROR_CODE_CONNECTION_TIMEOUT");
            if (!get_remote_test_flag() && !get_esco_busy_flag()) {
                __this->auto_connection_counter = (TIMEOUT_CONN_TIME * 1000);
                memcpy(__this->auto_connection_addr, bt->args, 6);
                if (__this->auto_connection_timer) {
                    sys_timer_del(__this->auto_connection_timer);
                    __this->auto_connection_timer = 0;
                }
                user_send_cmd_prepare(USER_CTRL_PAGE_CANCEL, 0, NULL);
                bt_wait_connect_and_phone_connect_switch(0);
                //user_send_cmd_prepare(USER_CTRL_START_CONNEC_VIA_ADDR, 6, bt->args);
            } else {
                bt_wait_phone_connect_control(1);
            }
            break;
        case ERROR_CODE_ACL_CONNECTION_ALREADY_EXISTS  :
            log_info("ERROR_CODE_ACL_CONNECTION_ALREADY_EXISTS");
            if (!get_remote_test_flag() && !get_esco_busy_flag()) {
                __this->auto_connection_counter = (8 * 1000);
                memcpy(__this->auto_connection_addr, bt->args, 6);
                if (__this->auto_connection_timer) {
                    sys_timer_del(__this->auto_connection_timer);
                    __this->auto_connection_timer = 0;
                }
                bt_wait_connect_and_phone_connect_switch(0);
            } else {
                bt_wait_phone_connect_control(1);
            }
            break;
        default:
            break;
        }

        break;
    default:
        break;
    }

    return 0;
}

int app_music_bt_event_handler(struct sys_event *event)
{
    if (event->from == BT_EVENT_FROM_CON) {
        return bt_connction_status_event_handler((struct bt_event *)event->payload);
    } else if (event->from == BT_EVENT_FROM_HCI) {
        return bt_hci_event_handler((struct bt_event *)event->payload);
    } else if (event->from == BT_EVENT_FROM_USER) {
        return 0;
    }
    return false;
}
