/*
 * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
 * Not a Contribution.
 *
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Changes from Qualcomm Innovation Center are provided under the following license:
 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
 * SPDX-License-Identifier: BSD-3-Clause-Clear
 *
 * 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_acdb"
//#define LOG_NDEBUG 0
#define LOG_NDDEBUG 0

#include <stdlib.h>
#include <dlfcn.h>
#include <log/log.h>
#include <cutils/list.h>
#include <time.h>
#include "acdb.h"
#include "platform_api.h"
#include "audio_extn.h"
#include <platform.h>

#ifdef INSTANCE_ID_ENABLED
int check_and_set_instance_id_support(struct mixer* mixer, bool acdb_support)
{
    const char *mixer_ctl_name = "Instance ID Support";
    struct mixer_ctl* ctl;

    ALOGV("%s", __func__);

    /* Check for ACDB and property instance ID support and issue mixer control */
    ctl = mixer_get_ctl_by_name(mixer, mixer_ctl_name);
    if (!ctl) {
        ALOGE("%s: Could not get ctl for mixer cmd - %s",
                               __func__, mixer_ctl_name);
        return -EINVAL;
    }

    ALOGD("%s: Final Instance ID support:%d\n", __func__, acdb_support);
    if (mixer_ctl_set_value(ctl, 0, acdb_support) < 0) {
        ALOGE("%s: Could not set Instance ID support %d", __func__,
              acdb_support);
        return -EINVAL;
    }
    return 0;
}
#else
#define check_and_set_instance_id_support(x, y) -ENOSYS
#endif

void get_platform_file_for_device(struct mixer *mixer, char* platform_info_file)
{
    const char *snd_card_name = NULL;

    if (mixer != NULL) {
        /* Get Sound card name */
        snd_card_name = mixer_get_name(mixer);
        if (!snd_card_name) {
            ALOGE("failed to allocate memory for snd_card_name");
            return;
        }
        /* Get platform info file for target */
        audio_extn_utils_get_platform_info(snd_card_name, platform_info_file);
    }
}

int acdb_init(int snd_card_num)
{

    int result = -1;
    struct mixer *mixer = NULL;

    if(snd_card_num < 0) {
        ALOGE("invalid sound card number");
        return result;
    }

    mixer = mixer_open(snd_card_num);
    if (!mixer) {
        ALOGE("%s: Unable to open the mixer card: %d", __func__,
               snd_card_num);
        return result;
    }
    result = acdb_init_v2(mixer);
    mixer_close(mixer);
    return result;
}

int acdb_init_v2(struct mixer *mixer)
{

    int result = -1;
    char *cvd_version = NULL;
    char vendor_config_path[VENDOR_CONFIG_PATH_MAX_LENGTH];
    char platform_info_file[VENDOR_CONFIG_FILE_MAX_LENGTH];
    const char *snd_card_name = NULL;
    struct acdb_platform_data *my_data = NULL;

    if (!mixer) {
       ALOGE("Invalid mixer handle");
       return result;
    }

    my_data = calloc(1, sizeof(struct acdb_platform_data));
    if (!my_data) {
        ALOGE("failed to allocate acdb platform data");
        goto cleanup;
    }

    list_init(&my_data->acdb_meta_key_list);
    audio_get_vendor_config_path(vendor_config_path, sizeof(vendor_config_path));
    /* Get path for platorm_info_xml_path_name in vendor */
    snprintf(platform_info_file, sizeof(platform_info_file),
            "%s/%s", vendor_config_path, PLATFORM_INFO_XML_PATH_NAME);
    get_platform_file_for_device(mixer, platform_info_file);
    /* Extract META KEY LIST INFO */
    platform_info_init(platform_info_file, my_data, ACDB_EXTN);

    my_data->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
    if (my_data->acdb_handle == NULL) {
        ALOGE("%s: DLOPEN failed for %s", __func__, LIB_ACDB_LOADER);
        goto cleanup;
    }

    ALOGV("%s: DLOPEN successful for %s", __func__, LIB_ACDB_LOADER);

    my_data->acdb_init_v4 = (acdb_init_v4_t)dlsym(my_data->acdb_handle,
                                                     "acdb_loader_init_v4");
    if (my_data->acdb_init_v4 == NULL)
        ALOGE("%s: dlsym error %s for acdb_loader_init_v4", __func__, dlerror());

    my_data->acdb_init_v3 = (acdb_init_v3_t)dlsym(my_data->acdb_handle,
                                                     "acdb_loader_init_v3");
    if (my_data->acdb_init_v3 == NULL)
        ALOGE("%s: dlsym error %s for acdb_loader_init_v3", __func__, dlerror());

    my_data->acdb_init_v2 = (acdb_init_v2_t)dlsym(my_data->acdb_handle,
                                                     "acdb_loader_init_v2");
    if (my_data->acdb_init_v2 == NULL)
        ALOGE("%s: dlsym error %s for acdb_loader_init_v2", __func__, dlerror());

    my_data->acdb_init = (acdb_init_t)dlsym(my_data->acdb_handle,
                                                 "acdb_loader_init_ACDB");
    if (my_data->acdb_init == NULL && my_data->acdb_init_v2 == NULL
        && my_data->acdb_init_v3 == NULL && my_data->acdb_init_v4 == NULL) {
        ALOGE("%s: dlsym error %s for acdb_loader_init_ACDB", __func__, dlerror());
        goto cleanup;
    }

    /* Get CVD version */
    cvd_version = calloc(1, MAX_CVD_VERSION_STRING_SIZE);
    if (!cvd_version) {
        ALOGE("%s: Failed to allocate cvd version", __func__);
        goto cleanup;
    } else {
        struct mixer_ctl *ctl = NULL;
        int count = 0;

        ctl = mixer_get_ctl_by_name(mixer, CVD_VERSION_MIXER_CTL);
        if (!ctl) {
            ALOGE("%s: Could not get ctl for mixer cmd - %s",  __func__, CVD_VERSION_MIXER_CTL);
#ifdef PLATFORM_AUTO
            ALOGE("%s: Ctl check bypassed in automotive platform for mixer cmd - %s",
                   __func__, CVD_VERSION_MIXER_CTL);
            goto get_sound_card_name;
#else
            goto cleanup;
#endif
        }
        mixer_ctl_update(ctl);

        count = mixer_ctl_get_num_values(ctl);
        if (count > MAX_CVD_VERSION_STRING_SIZE)
            count = MAX_CVD_VERSION_STRING_SIZE;

        result = mixer_ctl_get_array(ctl, cvd_version, count);
        if (result != 0) {
            ALOGE("%s: ERROR! mixer_ctl_get_array() failed to get CVD Version", __func__);
            goto cleanup;
        }
    }

#ifdef PLATFORM_AUTO
get_sound_card_name:
#endif
    /* Get Sound card name */
    snd_card_name = mixer_get_name(mixer);
    snd_card_name = platform_get_snd_card_name_for_acdb_loader(snd_card_name);
    if (!snd_card_name) {
        ALOGE("failed to get snd_card_name");
        result = -1;
        goto cleanup;
    }

    int key = 0;
    struct listnode *node = NULL;
    struct meta_key_list *key_info = NULL;
    static bool acdb_instance_id_support = false;

    my_data->acdb_init_data.cvd_version = cvd_version;
    my_data->acdb_init_data.snd_card_name = strdup(snd_card_name);
    my_data->acdb_init_data.meta_key_list = &my_data->acdb_meta_key_list;
    my_data->acdb_init_data.is_instance_id_supported = &acdb_instance_id_support;

    if (my_data->acdb_init_v4) {
        result = my_data->acdb_init_v4(&my_data->acdb_init_data, ACDB_LOADER_INIT_V4);
    } else if (my_data->acdb_init_v3) {
        result = my_data->acdb_init_v3(snd_card_name, cvd_version,
                                       &my_data->acdb_meta_key_list);
    } else if (my_data->acdb_init_v2) {
        node = list_head(&my_data->acdb_meta_key_list);
        key_info = node_to_item(node, struct meta_key_list, list);
        key = key_info->cal_info.nKey;
        result = my_data->acdb_init_v2(snd_card_name, cvd_version, key);
    } else {
        result = my_data->acdb_init();
    }
    ALOGD("%s: ACDB Instance ID support after ACDB init:%d\n",
          __func__, acdb_instance_id_support);
    check_and_set_instance_id_support(mixer, acdb_instance_id_support);

cleanup:
    if (NULL != my_data) {
        if (my_data->acdb_handle)
            dlclose(my_data->acdb_handle);

        struct listnode *node = NULL;
        struct meta_key_list *key_info = NULL;
        struct listnode *tempnode = NULL;
        list_for_each_safe(node, tempnode, &my_data->acdb_meta_key_list) {
            key_info = node_to_item(node, struct meta_key_list, list);
            list_remove(node);
            free(key_info);
        }

        if (result < 0) {

            if (snd_card_name)
                free((void *)snd_card_name);

            if (my_data->acdb_init_data.snd_card_name)
                free(my_data->acdb_init_data.snd_card_name);

            if (my_data)
                platform_info_deinit();
        }

        free(my_data);
    }

    if (cvd_version)
        free(cvd_version);

    return result;
}

int acdb_set_metainfo_key(void *platform, char *name, int key) {

    struct meta_key_list *key_info = (struct meta_key_list *)
                                        calloc(1, sizeof(struct meta_key_list));
    struct acdb_platform_data *pdata = (struct acdb_platform_data *)platform;
    if (!key_info) {
        ALOGE("%s: Could not allocate memory for key %d", __func__, key);
        return -ENOMEM;
    }

    key_info->cal_info.nKey = key;
    strlcpy(key_info->name, name, sizeof(key_info->name));
    list_add_tail(&pdata->acdb_meta_key_list, &key_info->list);

    ALOGD("%s: successfully added module %s and key %d to the list", __func__,
               key_info->name, key_info->cal_info.nKey);

    return 0;
}
