/*
 *  (C) 2014 DTS, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "audio_hw_dts_eagle"
/*#define LOG_NDEBUG 0*/

#include <errno.h>
#include <math.h>
#include <stdlib.h>
#include <fcntl.h>
#include <log/log.h>
#include <cutils/properties.h>
#include <cutils/str_parms.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sound/asound.h>
#include <sound/audio_effects.h>
#include <sound/devdep_params.h>
#include "audio_hw.h"
#include "platform.h"
#include "platform_api.h"

#ifdef DYNAMIC_LOG_ENABLED
#include <log_xml_parser.h>
#define LOG_MASK HAL_MOD_FILE_DTS_EAGLE
#include <log_utils.h>
#endif

#ifdef DTS_EAGLE

#define AUDIO_PARAMETER_KEY_DTS_EAGLE   "DTS_EAGLE"
#define STATE_NOTIFY_FILE               "/data/misc/dts/stream"
#define FADE_NOTIFY_FILE                "/data/misc/dts/fade"
#define DTS_EAGLE_KEY                   "DTS_EAGLE"
#define DEVICE_NODE                     "/dev/snd/hwC0D3"
#define MAX_LENGTH_OF_INTEGER_IN_STRING 13
#define PARAM_GET_MAX_SIZE              512

struct dts_eagle_param_desc_alsa {
    int alsa_effect_ID;
    struct dts_eagle_param_desc d;
};

static struct dts_eagle_param_desc_alsa *fade_in_data = NULL;
static struct dts_eagle_param_desc_alsa *fade_out_data = NULL;
static int32_t mDevices = 0;
static int32_t mCurrDevice = 0;
static const char* DTS_EAGLE_STR = DTS_EAGLE_KEY;

static int do_DTS_Eagle_params_stream(struct stream_out *out, struct dts_eagle_param_desc_alsa *t, bool get) {
    char mixer_string[128];
    char mixer_str_query[128];
    struct mixer_ctl *ctl;
    struct mixer_ctl *query_ctl;
    int pcm_device_id = platform_get_pcm_device_id(out->usecase, PCM_PLAYBACK);

    ALOGV("DTS_EAGLE_HAL (%s): enter", __func__);
    snprintf(mixer_string, sizeof(mixer_string), "%s %d", "Audio Effects Config", pcm_device_id);
    ctl = mixer_get_ctl_by_name(out->dev->mixer, mixer_string);
    if (!ctl) {
        ALOGE("DTS_EAGLE_HAL (%s): failed to open mixer %s", __func__, mixer_string);
    } else if (t) {
        int size = t->d.size + sizeof(struct dts_eagle_param_desc_alsa);
        ALOGD("DTS_EAGLE_HAL (%s): opened mixer %s", __func__, mixer_string);
        if (get) {
            ALOGD("DTS_EAGLE_HAL (%s): get request", __func__);
            snprintf(mixer_str_query, sizeof(mixer_str_query), "%s %d", "Query Audio Effect Param", pcm_device_id);
            query_ctl = mixer_get_ctl_by_name(out->dev->mixer, mixer_str_query);
            if (!query_ctl) {
                ALOGE("DTS_EAGLE_HAL (%s): failed to open mixer %s", __func__, mixer_str_query);
                return -EINVAL;
            }
            mixer_ctl_set_array(query_ctl, t, size);
            return mixer_ctl_get_array(ctl, t, size);
        }
        ALOGD("DTS_EAGLE_HAL (%s): set request", __func__);
        return mixer_ctl_set_array(ctl, t, size);
    } else {
        ALOGD("DTS_EAGLE_HAL (%s): parameter data NULL", __func__);
    }
    return -EINVAL;
}

static int do_DTS_Eagle_params(const struct audio_device *adev, struct dts_eagle_param_desc_alsa *t, bool get, const struct stream_out *out) {
    struct listnode *node;
    struct audio_usecase *usecase;
    int ret = 0, sent = 0, tret = 0;

    ALOGV("DTS_EAGLE_HAL (%s): enter", __func__);

    if (out) {
        /* if valid out stream is given, then send params to this stream only */
        tret = do_DTS_Eagle_params_stream(out, t, get);
        if (tret < 0)
            ret = tret;
        else
            sent = 1;
    } else {
        list_for_each(node, &adev->usecase_list) {
            usecase = node_to_item(node, struct audio_usecase, list);
            /* set/get eagle params for offload usecases only */
            if (usecase->stream.out && (usecase->type == PCM_PLAYBACK) && is_offload_usecase(usecase->id)) {
                tret = do_DTS_Eagle_params_stream(usecase->stream.out, t, get);
                if (tret < 0)
                    ret = tret;
                else
                    sent = 1;
            }
        }
    }

    if (!sent) {
        int fd = open(DEVICE_NODE, O_RDWR);

        if (get) {
            ALOGD("DTS_EAGLE_HAL (%s): no stream opened, attempting to retrieve directly from cache", __func__);
            t->d.device &= ~DTS_EAGLE_FLAG_ALSA_GET;
        } else {
            ALOGD("DTS_EAGLE_HAL (%s): no stream opened, attempting to send directly to cache", __func__);
            t->d.device |= DTS_EAGLE_FLAG_IOCTL_JUSTSETCACHE;
        }

        if (fd > 0) {
            int cmd = get ? DTS_EAGLE_IOCTL_GET_PARAM : DTS_EAGLE_IOCTL_SET_PARAM;
            if (ioctl(fd, cmd, &t->d) < 0) {
                ALOGE("DTS_EAGLE_HAL (%s): error sending/getting param\n", __func__);
                ret = -EINVAL;
            } else {
                ALOGD("DTS_EAGLE_HAL (%s): sent/retrieved param\n", __func__);
            }
            close(fd);
        } else {
            ALOGE("DTS_EAGLE_HAL (%s): couldn't open device %s\n", __func__, DEVICE_NODE);
            ret = -EINVAL;
        }
    }
    return ret;
}

static void fade_node(bool need_data) {
    char prop[PROPERTY_VALUE_MAX];
    property_get("vendor.audio.use.dts_eagle", prop, "0");
    if (strncmp("true", prop, sizeof("true")))
        return;
    int fd, n = 0;
    if ((fd = open(FADE_NOTIFY_FILE, O_TRUNC|O_WRONLY)) < 0) {
        ALOGV("No fade node, create one");
        fd = creat(FADE_NOTIFY_FILE, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
        if (fd < 0) {
            ALOGE("DTS_EAGLE_HAL (%s): Creating fade notifier node failed", __func__);
            return;
        }
        chmod(FADE_NOTIFY_FILE, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH);
    }
    char *str = need_data ? "need" : "have";
    n = write(fd, str, strlen(str));
    close(fd);
    if (n > 0)
        ALOGI("DTS_EAGLE_HAL (%s): fade notifier node set to \"%s\", %i bytes written", __func__, str, n);
    else
        ALOGE("DTS_EAGLE_HAL (%s): error writing to fade notifier node", __func__);
}

int audio_extn_dts_eagle_fade(const struct audio_device *adev, bool fade_in, const struct stream_out *out) {
    char prop[PROPERTY_VALUE_MAX];

    ALOGV("DTS_EAGLE_HAL (%s): enter with fade %s requested", __func__, fade_in ? "in" : "out");

    property_get("vendor.audio.use.dts_eagle", prop, "0");
    if (strncmp("true", prop, sizeof("true")))
        return 0;

    if (!fade_in_data || !fade_out_data)
        fade_node(true);

    if (fade_in) {
        if (fade_in_data)
            return do_DTS_Eagle_params(adev, fade_in_data, false, out);
    } else {
        if (fade_out_data)
            return do_DTS_Eagle_params(adev, fade_out_data, false, out);
    }
    return 0;
}

void audio_extn_dts_eagle_send_lic() {
    char prop[PROPERTY_VALUE_MAX] = {0};
    bool enabled;
    property_get("vendor.audio.use.dts_eagle", prop, "0");
    enabled = !strncmp("true", prop, sizeof("true")) || atoi(prop);
    if (!enabled)
        return;
    int fd = open(DEVICE_NODE, O_RDWR);
    int index = 1;
    if (fd >= 0) {
        if (ioctl(fd, DTS_EAGLE_IOCTL_SEND_LICENSE, &index) < 0) {
            ALOGE("DTS_EAGLE_HAL: error sending license after adsp ssr");
        } else {
            ALOGD("DTS_EAGLE_HAL: sent license after adsp ssr");
        }
        close(fd);
    } else {
        ALOGE("DTS_EAGLE_HAL: error opening eagle");
    }
    return;
}

void audio_extn_dts_eagle_set_parameters(struct audio_device *adev, struct str_parms *parms) {
    int ret, val;
    char value[32] = { 0 }, prop[PROPERTY_VALUE_MAX];

    ALOGV("DTS_EAGLE_HAL (%s): enter", __func__);

    property_get("vendor.audio.use.dts_eagle", prop, "0");
    if (strncmp("true", prop, sizeof("true")))
        return;

    memset(value, 0, sizeof(value));
    ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_DTS_EAGLE, value, sizeof(value));
    if (ret >= 0) {
        int *data = NULL, id, size, offset, count, dev, dts_found = 0, fade_in = 0;
        struct dts_eagle_param_desc_alsa *t2 = NULL, **t = &t2;

        ret = str_parms_get_str(parms, "fade", value, sizeof(value));
        if (ret >= 0) {
            fade_in = atoi(value);
            if (fade_in > 0) {
                t = (fade_in == 1) ? &fade_in_data : &fade_out_data;
            }
        }

        ret = str_parms_get_str(parms, "count", value, sizeof(value));
        if (ret >= 0) {
            count = atoi(value);
            if (count > 1) {
                int tmp_size = count * 32;
                char *tmp = malloc(tmp_size+1);
                data = malloc(sizeof(int) * count);
                ALOGV("DTS_EAGLE_HAL (%s): multi count param detected, count: %d", __func__, count);
                if (data && tmp) {
                    ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_DTS_EAGLE, tmp, tmp_size);
                    if (ret >= 0) {
                        int idx = 0, tidx, tcnt = 0;
                        dts_found = 1;
                        do {
                            sscanf(&tmp[idx], "%i", &data[tcnt]);
                            tidx = strcspn(&tmp[idx], ",");
                            if (idx + tidx >= ret && tcnt < count-1) {
                                ALOGE("DTS_EAGLE_HAL (%s): malformed multi value string.", __func__);
                                dts_found = 0;
                                break;
                            }
                            ALOGD("DTS_EAGLE_HAL (%s): %i:%i (next %s)", __func__, tcnt, data[tcnt], &tmp[idx+tidx]);
                            idx += tidx + 1;
                            tidx = 0;
                            tcnt++;
                        } while (tcnt < count);
                    }
                } else {
                    ALOGE("DTS_EAGLE_HAL (%s): mem alloc for multi count param parse failed.", __func__);
                }
                free(tmp);
            }
        }

        if (!dts_found) {
            data = malloc(sizeof(int));
            if (data) {
                ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_DTS_EAGLE, value, sizeof(value));
                if (ret >= 0) {
                    *data = atoi(value);
                    dts_found = 1;
                    count = 1;
                } else {
                    ALOGE("DTS_EAGLE_HAL (%s): malformed value string.", __func__);
                }
            } else {
                ALOGE("DTS_EAGLE_HAL (%s): mem alloc for param parse failed.", __func__);
            }
        }

        if (dts_found) {
            dts_found = 0;
            ret = str_parms_get_str(parms, "id", value, sizeof(value));
            if (ret >= 0) {
                if (sscanf(value, "%x", &id) == 1) {
                    ret = str_parms_get_str(parms, "size", value, sizeof(value));
                    if (ret >= 0) {
                        size = atoi(value);
                        ret = str_parms_get_str(parms, "offset", value, sizeof(value));
                        if (ret >= 0) {
                            offset = atoi(value);
                            ret = str_parms_get_str(parms, "device", value, sizeof(value));
                            if (ret >= 0) {
                                dev = atoi(value);
                                dts_found = 1;
                            }
                        }
                    }
                }
            }
        }

        if (dts_found && count > 1 && size != (int)(count * sizeof(int))) {
            ALOGE("DTS_EAGLE_HAL (%s): size/count mismatch (size = %i bytes, count = %i integers / %u bytes).", __func__, size, count, count*sizeof(int));
        } else if (dts_found) {
            ALOGI("DTS_EAGLE_HAL (%s): param detected: %s", __func__, str_parms_to_str(parms));
            if (!(*t))
                *t = (struct dts_eagle_param_desc_alsa*)malloc(sizeof(struct dts_eagle_param_desc_alsa) + size);
            if (*t) {
                (*t)->alsa_effect_ID = DTS_EAGLE_MODULE;
                (*t)->d.id = id;
                (*t)->d.size = size;
                (*t)->d.offset = offset;
                (*t)->d.device = dev;
                memcpy((void*)((char*)*t + sizeof(struct dts_eagle_param_desc_alsa)), data, size);
                ALOGD("DTS_EAGLE_HAL (%s): id: 0x%X, size: %d, offset: %d, device: %d", __func__,
                       (*t)->d.id, (*t)->d.size, (*t)->d.offset, (*t)->d.device);
                if (!fade_in) {
                    ret = do_DTS_Eagle_params(adev, *t, false, NULL);
                    if (ret < 0)
                        ALOGE("DTS_EAGLE_HAL (%s): failed setting params in kernel with error %i", __func__, ret);
                }
                free(t2);
            } else {
                ALOGE("DTS_EAGLE_HAL (%s): mem alloc for dsp structure failed.", __func__);
            }
        } else {
            ALOGE("DTS_EAGLE_HAL (%s): param detected but failed parse: %s", __func__, str_parms_to_str(parms));
        }
        free(data);

        if (fade_in > 0 && fade_in_data && fade_out_data)
            fade_node(false);
    }
    ALOGV("DTS_EAGLE_HAL (%s): exit", __func__);
}

int audio_extn_dts_eagle_get_parameters(const struct audio_device *adev,
                  struct str_parms *query, struct str_parms *reply) {
    int ret, val;
    char value[32] = { 0 }, prop[PROPERTY_VALUE_MAX];
    char params[PARAM_GET_MAX_SIZE];

    ALOGV("DTS_EAGLE_HAL (%s): enter", __func__);

    property_get("vendor.audio.use.dts_eagle", prop, "0");
    if (strncmp("true", prop, sizeof("true")))
        return 0;

    ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_DTS_EAGLE, value, sizeof(value));
    if (ret >= 0) {
        int *data = NULL, id = 0, size = 0, offset = 0,
            count = 1, dev = 0, idx = 0, dts_found = 0, i = 0;
        const size_t chars_4_int = 16;
        ret = str_parms_get_str(query, "count", value, sizeof(value));
        if (ret >= 0) {
            count = atoi(value);
            if (count > 1) {
                ALOGV("DTS_EAGLE_HAL (%s): multi count param detected, count: %d", __func__, count);
            } else {
                count = 1;
            }
        }

        ret = str_parms_get_str(query, "id", value, sizeof(value));
        if (ret >= 0) {
            if (sscanf(value, "%x", &id) == 1) {
                ret = str_parms_get_str(query, "size", value, sizeof(value));
                if (ret >= 0) {
                    size = atoi(value);
                    ret = str_parms_get_str(query, "offset", value, sizeof(value));
                    if (ret >= 0) {
                        offset = atoi(value);
                        ret = str_parms_get_str(query, "device", value, sizeof(value));
                        if (ret >= 0) {
                            dev = atoi(value);
                            dts_found = 1;
                        }
                    }
                }
            }
        }

        if (dts_found) {
            ALOGI("DTS_EAGLE_HAL (%s): param (get) detected: %s", __func__, str_parms_to_str(query));
            struct dts_eagle_param_desc_alsa *t = (struct dts_eagle_param_desc_alsa *)params;
            if (t) {
                char buf[chars_4_int*count];
                t->alsa_effect_ID = DTS_EAGLE_MODULE;
                t->d.id = id;
                t->d.size = size;
                t->d.offset = offset;
                t->d.device = dev;
                ALOGV("DTS_EAGLE_HAL (%s): id (get): 0x%X, size: %d, offset: %d, device: %d", __func__,
                       t->d.id, t->d.size, t->d.offset, t->d.device & 0x7FFFFFFF);
                if ((sizeof(struct dts_eagle_param_desc_alsa) + size) > PARAM_GET_MAX_SIZE) {
                    ALOGE("%s: requested data too large", __func__);
                    return -1;
                }
                ret = do_DTS_Eagle_params(adev, t, true, NULL);
                if (ret >= 0) {
                    data = (int*)(params + sizeof(struct dts_eagle_param_desc_alsa));
                    for (i = 0; i < count; i++)
                        idx += snprintf(&buf[idx], chars_4_int, "%i,", data[i]);
                    buf[idx > 0 ? idx-1 : 0] = 0;
                    ALOGD("DTS_EAGLE_HAL (%s): get result: %s", __func__, buf);
                    str_parms_add_int(reply, "size", size);
                    str_parms_add_str(reply, AUDIO_PARAMETER_KEY_DTS_EAGLE, buf);
                    str_parms_add_int(reply, "count", count);
                    snprintf(value, sizeof(value), "0x%x", id);
                    str_parms_add_str(reply, "id", value);
                    str_parms_add_int(reply, "device", dev);
                    str_parms_add_int(reply, "offset", offset);
                    ALOGV("DTS_EAGLE_HAL (%s): reply: %s", __func__, str_parms_to_str(reply));
                } else {
                    ALOGE("DTS_EAGLE_HAL (%s): failed getting params from kernel with error %i", __func__, ret);
                    return -1;
                }
            } else {
                ALOGE("DTS_EAGLE_HAL (%s): mem alloc for (get) dsp structure failed.", __func__);
                return -1;
            }
        } else {
            ALOGE("DTS_EAGLE_HAL (%s): param (get) detected but failed parse: %s", __func__, str_parms_to_str(query));
            return -1;
        }
    }

    ALOGV("DTS_EAGLE_HAL (%s): exit", __func__);
    return 0;
}

void audio_extn_dts_create_state_notifier_node(int stream_out)
{
    char prop[PROPERTY_VALUE_MAX];
    char path[PATH_MAX];
    char value[MAX_LENGTH_OF_INTEGER_IN_STRING];
    int fd;
    property_get("vendor.audio.use.dts_eagle", prop, "0");
    if ((!strncmp("true", prop, sizeof("true")) || atoi(prop))) {
        ALOGV("DTS_EAGLE_NODE_STREAM (%s): create_state_notifier_node - stream_out: %d", __func__, stream_out);
        strlcpy(path, STATE_NOTIFY_FILE, sizeof(path));
        snprintf(value, sizeof(value), "%d", stream_out);
        strlcat(path, value, sizeof(path));

        if ((fd=open(path, O_RDONLY)) < 0) {
            ALOGV("DTS_EAGLE_NODE_STREAM (%s): no file exists", __func__);
        } else {
            ALOGV("DTS_EAGLE_NODE_STREAM (%s): a file with the same name exists, removing it before creating it", __func__);
            close(fd);
            remove(path);
        }
        if ((fd=creat(path, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0) {
            ALOGE("DTS_EAGLE_NODE_STREAM (%s): opening state notifier node failed returned", __func__);
            return;
        }
        chmod(path, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH);
        ALOGV("DTS_EAGLE_NODE_STREAM (%s): opening state notifier node successful", __func__);
        close(fd);
        if (!fade_in_data || !fade_out_data)
            fade_node(true);
    }
}

void audio_extn_dts_notify_playback_state(int stream_out, int has_video, int sample_rate,
                           int channels, int is_playing) {
    char prop[PROPERTY_VALUE_MAX];
    char path[PATH_MAX];
    char value[MAX_LENGTH_OF_INTEGER_IN_STRING];
    char buf[1024];
    int fd;
    property_get("vendor.audio.use.dts_eagle", prop, "0");
    if ((!strncmp("true", prop, sizeof("true")) || atoi(prop))) {
        ALOGV("DTS_EAGLE_NODE_STREAM (%s): notify_playback_state - is_playing: %d", __func__, is_playing);
        strlcpy(path, STATE_NOTIFY_FILE, sizeof(path));
        snprintf(value, sizeof(value), "%d", stream_out);
        strlcat(path, value, sizeof(path));
        if ((fd=open(path, O_TRUNC|O_WRONLY)) < 0) {
            ALOGE("DTS_EAGLE_NODE_STREAM (%s): open state notifier node failed", __func__);
        } else {
            snprintf(buf, sizeof(buf), "has_video=%d;sample_rate=%d;channel_mode=%d;playback_state=%d",
                     has_video, sample_rate, channels, is_playing);
            int n = write(fd, buf, strlen(buf));
            if (n > 0)
                ALOGV("DTS_EAGLE_NODE_STREAM (%s): write to state notifier node successful, bytes written: %d", __func__, n);
            else
                ALOGE("DTS_EAGLE_NODE_STREAM (%s): write state notifier node failed", __func__);
            close(fd);
        }
    }
}

void audio_extn_dts_remove_state_notifier_node(int stream_out)
{
    char prop[PROPERTY_VALUE_MAX];
    char path[PATH_MAX];
    char value[MAX_LENGTH_OF_INTEGER_IN_STRING];
    int fd;
    property_get("vendor.audio.use.dts_eagle", prop, "0");
    if ((!strncmp("true", prop, sizeof("true")) || atoi(prop)) && (stream_out)) {
        ALOGV("DTS_EAGLE_NODE_STREAM (%s): remove_state_notifier_node: stream_out - %d", __func__, stream_out);
        strlcpy(path, STATE_NOTIFY_FILE, sizeof(path));
        snprintf(value, sizeof(value), "%d", stream_out);
        strlcat(path, value, sizeof(path));
        if ((fd=open(path, O_RDONLY)) < 0) {
            ALOGV("DTS_EAGLE_NODE_STREAM (%s): open state notifier node failed", __func__);
        } else {
            ALOGV("DTS_EAGLE_NODE_STREAM (%s): open state notifier node successful, removing the file", __func__);
            close(fd);
            remove(path);
        }
    }
}

#endif /* DTS_EAGLE end */
