#include "server/audio_server.h"
#include "server/server_core.h"
#include "app_config.h"
#include "storage_device.h"
#include "event/key_event.h"
#include "event/device_event.h"
#include "event/net_event.h"
#include "syscfg/syscfg_id.h"
#include "system/wait.h"
#include "system/app_core.h"
#include "lwip.h"

#include "server/ai_server.h"
#include "network_download/net_download.h"

#define INIT_VOLUME_VALUE   30
#define URL "http://bdcloud-player-new.cdn.bcebos.com/testaudio/mp3/Hotel%20California-The%20Eagles.mp3"
/*#define URL "http://lw.sycdn.kuwo.cn/346f777dc8ad83ef9953e88c5cbc4c7b/676a2242/resource/30106/" \
    "trackmedia/C200003ryaYw2nWz55.m4a?bitrate$48&format$aac&" \
    "source$kwplayer_ar_5.1.0.0_B_jiakong_vh.apk&type$convert_url_with_sign"
    */

struct net_music_hdl {
    char volume;
    u16 wait_download;
    int download_ready;
    int play_time;
    int total_time;
    void *net_file;
    struct server *dec_server;
    struct audio_dec_breakpoint dec_bp;
};

static struct net_music_hdl net_music_handler;

#define __this 	(&net_music_handler)

//网络解码需要的数据访问句柄
static const struct audio_vfs_ops net_audio_dec_vfs_ops = {
    .fread = net_download_read,
    .fseek = net_download_seek,
    .flen  = net_download_get_file_len,
};

//检查音频需要的格式检查数据头部是否下载缓冲完成
static int __net_download_ready(void *p)
{
    __this->download_ready = net_download_check_ready(__this->net_file);
    if (__this->download_ready) {
        return 1;
    }
    return 0;
}

//停止播放
static int net_music_dec_stop(void)
{
    union audio_req r = {0};
    union ai_req req = {0};

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

    log_i("net_music_dec_stop\n");

    net_download_buf_inactive(__this->net_file);

    if (__this->wait_download) {
        /*
         * 歌曲还未开始播放，删除wait
         */
        /* sys_timer_del(__this->wait_download); */
        wait_completion_del(__this->wait_download);
        __this->wait_download = 0;
    } else {
        r.dec.cmd = AUDIO_DEC_STOP;
        server_request(__this->dec_server, AUDIO_REQ_DEC, &r);

        int argv[2];
        argv[0] = AUDIO_SERVER_EVENT_END;
        argv[1] = (int)__this->net_file;
        server_event_handler_del(__this->dec_server, 2, argv);
    }

    extern int lwip_canceladdrinfo(void);
    lwip_canceladdrinfo();
    //释放网络下载资源
    net_download_close(__this->net_file);
    __this->net_file = NULL;

    return 0;
}

//播放结束
static int net_music_dec_end(void)
{
    union ai_req req = {0};

    log_i("net_music_dec_end\n");

    net_music_dec_stop();

    return 0;
}

// 混音解码器播放失败处理函数
static int __net_music_dec_file_failed_handler(void *file)
{
    printf("play_net_music_faild\n");
    union audio_req req = {0};

    net_download_buf_inactive(file);

    req.dec.cmd = AUDIO_DEC_STOP;
    server_request(__this->dec_server, AUDIO_REQ_DEC, &req);

    net_download_close(file);
    __this->net_file = NULL;

    return -1;
}

//数据缓冲已完成，开始解码
static int __net_music_dec_file(void *file)
{
    int err = 0;
    union ai_req r = {0};
    union audio_req req = {0};

    __this->wait_download = 0;

    if (__this->download_ready < 0) {
        /* 网络下载失败 */
        return __net_music_dec_file_failed_handler(file);
    }

    //获取网络资源的格式
    //extern char* get_net_music_media_type(void);
    //req.dec.dec_type = get_net_music_media_type();
    printf("url_file_type: %s\n", req.dec.dec_type);

    net_download_set_read_timeout(file, 5000);

    req.dec.cmd             = AUDIO_DEC_OPEN;
    req.dec.volume          = __this->volume;
    req.dec.output_buf_len  = 6 * 1024;
    req.dec.file            = (FILE *)file;
    req.dec.channel         = 0;
    req.dec.sample_rate     = 0;
    req.dec.priority        = 1;
    req.dec.vfs_ops         = &net_audio_dec_vfs_ops;
    req.dec.sample_source   = CONFIG_AUDIO_DEC_PLAY_SOURCE;

    err = server_request(__this->dec_server, AUDIO_REQ_DEC, &req);
    if (err) {
        return __net_music_dec_file_failed_handler(file);
    }

    net_download_set_read_timeout(file, 0);

    req.dec.cmd = AUDIO_DEC_START;

    server_request(__this->dec_server, AUDIO_REQ_DEC, &req);

    net_download_set_pp(file, 0);

    return 0;
}

static int net_music_dec_file(const char *url)
{
    int err = 0;
    struct net_download_parm parm = {0};

    net_music_dec_stop();

    if (!url) {
        return -1;
    }

    log_i("net_download_open\n");

    parm.url                = url;
    //网络缓冲buf大小
#ifdef CONFIG_NO_SDRAM_ENABLE
    parm.cbuf_size          = 150 * 1024;
#else
    parm.cbuf_size          = 500 * 1024;
#endif
    //设置网络下载超时
    parm.timeout_millsec    = 10000;
    parm.seek_threshold     = 1024 * 200;	//用户可适当调整
    /* parm.seek_low_range     = __this->dec_bp.fptr;    //恢复断点时设置网络的开始下载地址 */

    err = net_download_open(&__this->net_file, &parm);
    if (err) {
        log_e("net_download_open: err = %d\n", err);
        return err;
    }

    /*异步等待网络下载ready，防止网络阻塞导致app_core卡住 */
    __this->wait_download = wait_completion(__net_download_ready,
                                            (int (*)(void *))__net_music_dec_file, __this->net_file, NULL);

    return 0;
}

//获取解码器状态
static int net_music_get_dec_status(void)
{
    union audio_req req = {0};

    req.dec.cmd     = AUDIO_DEC_GET_STATUS;
    server_request(__this->dec_server, AUDIO_REQ_DEC, &req);

    return req.dec.status;
}

static void dec_server_event_handler(void *priv, int argc, int *argv)
{
    switch (argv[0]) {
    case AUDIO_SERVER_EVENT_ERR:
        log_i("net_music: AUDIO_SERVER_EVENT_ERR\n");
    case AUDIO_SERVER_EVENT_END:
        log_i("net_music: AUDIO_SERVER_EVENT_END\n");
        net_music_dec_end();
        break;
    case AUDIO_SERVER_EVENT_CURR_TIME:
        log_d("play_time: %d\n", argv[1]);
        __this->play_time = argv[1];
        break;
    }
}

static int net_music_mode_init(void)
{
    log_i("net_music_play_main\n");

    memset(__this, 0, sizeof(struct net_music_hdl));

    __this->volume = INIT_VOLUME_VALUE;

    __this->dec_server = server_open("audio_server", "dec");
    if (!__this->dec_server) {
        return -1;
    }
    server_register_event_handler_to_task(__this->dec_server, NULL, dec_server_event_handler, "app_core");

    return 0;
}

static void net_music_mode_exit(void)
{
    net_music_dec_stop();
    server_close(__this->dec_server);
    __this->dec_server = NULL;
}

static int net_music_key_click(struct key_event *key)
{
    int ret = true;

    switch (key->value) {
    case KEY_OK:
        net_music_dec_file(URL);
        break;
    default:
        ret = false;
        break;
    }

    return ret;
}

static int net_music_key_event_handler(struct key_event *key)
{
    switch (key->action) {
    case KEY_EVENT_CLICK:
        return net_music_key_click(key);
    default:
        break;
    }

    return true;
}

static int net_music_event_handler(struct application *app, struct sys_event *event)
{
    switch (event->type) {
    case SYS_KEY_EVENT:

        return net_music_key_event_handler((struct key_event *)event->payload);
    default:
        return false;
    }
}

static int net_music_state_machine(struct application *app, enum app_state state, struct intent *it)
{
    switch (state) {
    case APP_STA_CREATE:
        break;
    case APP_STA_START:
        net_music_mode_init();
        break;
    case APP_STA_PAUSE:
        break;
    case APP_STA_RESUME:
        break;
    case APP_STA_STOP:
        net_music_mode_exit();
        break;
    case APP_STA_DESTROY:
        break;
    }

    return 0;
}

static const struct application_operation net_music_ops = {
    .state_machine  = net_music_state_machine,
    .event_handler 	= net_music_event_handler,
};

REGISTER_APPLICATION(net_music) = {
    .name 	= "net_music",
    .ops 	= &net_music_ops,
    .state  = APP_STA_DESTROY,
};
