/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * 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_utils"
//#define LOG_NDEBUG 0

#include <errno.h>
#include <cutils/properties.h>
#include <cutils/config_utils.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <unistd.h>
#include <cutils/str_parms.h>
#include <log/log.h>
#include <cutils/misc.h>

#include "acdb.h"
#include "audio_hw.h"
#include "platform.h"
#include "platform_api.h"
#include "audio_extn.h"

#define MAX_LENGTH_MIXER_CONTROL_IN_INT 128

static int set_stream_app_type_mixer_ctrl(struct audio_device *adev,
                                          int pcm_device_id, int app_type,
                                          int acdb_dev_id, int sample_rate,
                                          int stream_type,
                                          snd_device_t snd_device)
{

    char mixer_ctl_name[MAX_LENGTH_MIXER_CONTROL_IN_INT];
    struct mixer_ctl *ctl;
    int app_type_cfg[MAX_LENGTH_MIXER_CONTROL_IN_INT], len = 0, rc = 0;
    int snd_device_be_idx = -1;

    if (stream_type == PCM_PLAYBACK) {
        snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
             "Audio Stream %d App Type Cfg", pcm_device_id);
    } else if (stream_type == PCM_CAPTURE) {
        snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
             "Audio Stream Capture %d App Type Cfg", pcm_device_id);
    }

    ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
    if (!ctl) {
        ALOGE("%s: Could not get ctl for mixer cmd - %s",
             __func__, mixer_ctl_name);
        rc = -EINVAL;
        goto exit;
    }
    app_type_cfg[len++] = app_type;
    app_type_cfg[len++] = acdb_dev_id;
    app_type_cfg[len++] = sample_rate;

    snd_device_be_idx = platform_get_snd_device_backend_index(snd_device);
    if (snd_device_be_idx > 0)
        app_type_cfg[len++] = snd_device_be_idx;
    ALOGV("%s: stream type %d app_type %d, acdb_dev_id %d "
          "sample rate %d, snd_device_be_idx %d",
          __func__, stream_type, app_type, acdb_dev_id, sample_rate,
          snd_device_be_idx);
    mixer_ctl_set_array(ctl, app_type_cfg, len);

exit:
    return rc;
}

void audio_extn_utils_send_default_app_type_cfg(void *platform, struct mixer *mixer)
{
    int app_type_cfg[MAX_LENGTH_MIXER_CONTROL_IN_INT] = {-1};
    int length = 0, app_type = 0,rc = 0;
    struct mixer_ctl *ctl = NULL;
    const char *mixer_ctl_name = "App Type Config";

    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;
    }
    rc = platform_get_default_app_type_v2(platform, PCM_PLAYBACK, &app_type);
    if (rc == 0) {
        app_type_cfg[length++] = 1;
        app_type_cfg[length++] = app_type;
        app_type_cfg[length++] = 48000;
        app_type_cfg[length++] = 16;
        mixer_ctl_set_array(ctl, app_type_cfg, length);
    }
    return;
}

static const char *flags_to_mode(int dir, uint32_t flags)
{
    if (dir == 0) {
        if (flags & AUDIO_OUTPUT_FLAG_VOIP_RX) {
            return "voip";
        }
    } else if (dir == 1) {
        if (flags & AUDIO_INPUT_FLAG_VOIP_TX) {
            return "voip";
        }
    }
    return "default";
}

static int audio_extn_utils_send_app_type_cfg_hfp(struct audio_device *adev,
                                       struct audio_usecase *usecase)
{
    struct mixer_ctl *ctl;
    int pcm_device_id, acdb_dev_id = 0, snd_device = usecase->out_snd_device;
    int32_t sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
    int app_type = 0, rc = 0;

    ALOGV("%s", __func__);

    if (usecase->type != PCM_HFP_CALL) {
        ALOGV("%s: not a playback or HFP path, no need to cfg app type", __func__);
        rc = 0;
        goto exit_send_app_type_cfg;
    }
    if ((usecase->id != USECASE_AUDIO_HFP_SCO) &&
        (usecase->id != USECASE_AUDIO_HFP_SCO_WB)) {
        ALOGV("%s: a playback path where app type cfg is not required", __func__);
        rc = 0;
        goto exit_send_app_type_cfg;
    }

    snd_device = usecase->out_snd_device;
    pcm_device_id = platform_get_pcm_device_id(usecase->id, PCM_PLAYBACK);

    acdb_dev_id = platform_get_snd_device_acdb_id(snd_device);
    if (acdb_dev_id < 0) {
        ALOGE("%s: Couldn't get the acdb dev id", __func__);
        rc = -EINVAL;
        goto exit_send_app_type_cfg;
    }

    if (usecase->type == PCM_HFP_CALL) {

        /* config HFP session:1 playback path */
        rc = platform_get_default_app_type_v2(adev->platform, PCM_PLAYBACK, &app_type);
        if (rc < 0)
            goto exit_send_app_type_cfg;

        sample_rate= CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
        rc = set_stream_app_type_mixer_ctrl(adev, pcm_device_id, app_type,
                                            acdb_dev_id, sample_rate,
                                            PCM_PLAYBACK,
                                            SND_DEVICE_NONE); // use legacy behavior
        if (rc < 0)
            goto exit_send_app_type_cfg;
        /* config HFP session:1 capture path */
        rc = platform_get_default_app_type_v2(adev->platform, PCM_CAPTURE, &app_type);

        if (rc == 0) {
            rc = set_stream_app_type_mixer_ctrl(adev, pcm_device_id, app_type,
                                                acdb_dev_id, sample_rate,
                                                PCM_CAPTURE,
                                                SND_DEVICE_NONE);
            if (rc < 0)
                goto exit_send_app_type_cfg;
        }
        /* config HFP session:2 capture path */
        pcm_device_id = HFP_ASM_RX_TX;
        snd_device = usecase->in_snd_device;
        acdb_dev_id = platform_get_snd_device_acdb_id(snd_device);
        if (acdb_dev_id <= 0) {
            ALOGE("%s: Couldn't get the acdb dev id", __func__);
            rc = -EINVAL;
            goto exit_send_app_type_cfg;
        }
        rc = platform_get_default_app_type_v2(adev->platform, PCM_CAPTURE, &app_type);
        if (rc == 0) {
            rc = set_stream_app_type_mixer_ctrl(adev, pcm_device_id, app_type,
                                                acdb_dev_id, sample_rate, PCM_CAPTURE,
                                                SND_DEVICE_NONE);
            if (rc < 0)
                goto exit_send_app_type_cfg;
        }

        /* config HFP session:2 playback path */
        rc = platform_get_default_app_type_v2(adev->platform, PCM_PLAYBACK, &app_type);
        if (rc == 0) {
            rc = set_stream_app_type_mixer_ctrl(adev, pcm_device_id, app_type,
                                acdb_dev_id, sample_rate,
                                PCM_PLAYBACK, SND_DEVICE_NONE);
            if (rc < 0)
                goto exit_send_app_type_cfg;
        }
    }

    rc = 0;
exit_send_app_type_cfg:
    return rc;
}


static int derive_capture_app_type_cfg(struct audio_device *adev,
                                       struct audio_usecase *usecase,
                                       int *app_type,
                                       int *sample_rate)
{
    if (usecase->stream.in == NULL) {
        return -1;
    }
    struct stream_in *in = usecase->stream.in;
    struct stream_app_type_cfg *app_type_cfg = &in->app_type_cfg;

    *sample_rate = DEFAULT_INPUT_SAMPLING_RATE;
    if (audio_is_usb_in_device(in->device)) {
        platform_check_and_update_copp_sample_rate(adev->platform,
                                                   usecase->in_snd_device,
                                                   in->sample_rate,
                                                   sample_rate);
    }

    app_type_cfg->mode = flags_to_mode(1 /*capture*/, in->flags);
    ALOGV("%s mode %s", __func__, app_type_cfg->mode);
    if (in->format == AUDIO_FORMAT_PCM_16_BIT) {
        platform_get_app_type_v2(adev->platform,
                                 PCM_CAPTURE,
                                 app_type_cfg->mode,
                                 16,
                                 app_type_cfg->sample_rate,
                                 app_type);
    } else if (in->format == AUDIO_FORMAT_PCM_24_BIT_PACKED ||
               in->format == AUDIO_FORMAT_PCM_8_24_BIT) {
        platform_get_app_type_v2(adev->platform,
                                 PCM_CAPTURE,
                                 app_type_cfg->mode,
                                 24,
                                 app_type_cfg->sample_rate,
                                 app_type);
    } else if (in->format == AUDIO_FORMAT_PCM_32_BIT) {
        platform_get_app_type_v2(adev->platform,
                                 PCM_CAPTURE,
                                 app_type_cfg->mode,
                                 32,
                                 app_type_cfg->sample_rate,
                                 app_type);
    } else {
        ALOGE("%s bad format\n", __func__);
        return -1;
    }

    app_type_cfg->app_type = *app_type;
    app_type_cfg->sample_rate = *sample_rate;
    return 0;
}

static int derive_playback_app_type_cfg(struct audio_device *adev,
                                        struct audio_usecase *usecase,
                                        int *app_type,
                                        int *sample_rate)
{
    if (usecase->stream.out == NULL) {
        return -1;
    }
    struct stream_out *out = usecase->stream.out;
    struct stream_app_type_cfg *app_type_cfg = &out->app_type_cfg;

    *sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;

    // add speaker prot changes if needed
    // and use that to check for device
    if (audio_is_usb_out_device(out->devices)) {
        platform_check_and_update_copp_sample_rate(adev->platform,
                                                   usecase->out_snd_device,
                                                   out->sample_rate,
                                                   sample_rate);
    }

    app_type_cfg->mode = flags_to_mode(0 /*playback*/, out->flags);
    if (!audio_is_linear_pcm(out->format)) {
        platform_get_app_type_v2(adev->platform,
                                 PCM_PLAYBACK,
                                 app_type_cfg->mode,
                                 24,
                                 *sample_rate,
                                 app_type);
        ALOGV("Non pcm got app type %d", *app_type);
    } else if (out->format == AUDIO_FORMAT_PCM_16_BIT) {
        platform_get_app_type_v2(adev->platform,
                                 PCM_PLAYBACK,
                                 app_type_cfg->mode,
                                 16,
                                 *sample_rate,
                                 app_type);
    } else if (out->format == AUDIO_FORMAT_PCM_24_BIT_PACKED ||
               out->format == AUDIO_FORMAT_PCM_8_24_BIT) {
        platform_get_app_type_v2(adev->platform,
                                 PCM_PLAYBACK,
                                 app_type_cfg->mode,
                                 24,
                                 *sample_rate,
                                 app_type);
    } else if (out->format == AUDIO_FORMAT_PCM_32_BIT) {
        platform_get_app_type_v2(adev->platform,
                                 PCM_PLAYBACK,
                                 app_type_cfg->mode,
                                 32,
                                 *sample_rate,
                                 app_type);
    } else {
        ALOGE("%s bad format\n", __func__);
        return -1;
    }

    app_type_cfg->app_type = *app_type;
    app_type_cfg->sample_rate = *sample_rate;
    return 0;
}

static int derive_acdb_dev_id(struct audio_device *adev __unused,
                              struct audio_usecase *usecase)
{
    struct stream_out *out;
    struct stream_in *in;

    if (usecase->type == PCM_PLAYBACK) {
        return platform_get_snd_device_acdb_id(usecase->out_snd_device);
    } else if(usecase->type == PCM_CAPTURE) {
        return platform_get_snd_device_acdb_id(usecase->in_snd_device);
    }
    return -1;
}

int audio_extn_utils_send_app_type_cfg(struct audio_device *adev,
                                       struct audio_usecase *usecase)
{
    int len = 0;
    int sample_rate;
    int app_type;
    int acdb_dev_id;
    size_t app_type_cfg[MAX_LENGTH_MIXER_CONTROL_IN_INT] = {0};
    char mixer_ctl_name[MAX_LENGTH_MIXER_CONTROL_IN_INT] = {0};
    int pcm_device_id;
    struct mixer_ctl *ctl;
    int ret;

    if (usecase->type == PCM_HFP_CALL) {
        return audio_extn_utils_send_app_type_cfg_hfp(adev, usecase);
    }

    if (!platform_supports_app_type_cfg())
        return -1;

    if (usecase->type == PCM_PLAYBACK) {
        ret = derive_playback_app_type_cfg(adev,
                                           usecase,
                                           &app_type,
                                           &sample_rate);
    } else if (usecase->type == PCM_CAPTURE) {
        ret = derive_capture_app_type_cfg(adev,
                                          usecase,
                                          &app_type,
                                          &sample_rate);
    } else {
        ALOGE("%s: Invalid uc type : 0x%x", __func__, usecase->type);
        return -1;
    }

    if (ret < 0) {
        ALOGE("%s: Failed to derive app_type for uc type : 0x%x", __func__,
              usecase->type);
        return -1;
    }

    acdb_dev_id = derive_acdb_dev_id(adev, usecase);
    if (acdb_dev_id <= 0) {
        ALOGE("%s: Couldn't get the acdb dev id", __func__);
        return -1;
    }

    pcm_device_id = platform_get_pcm_device_id(usecase->id, usecase->type);
    set_stream_app_type_mixer_ctrl(adev, pcm_device_id, app_type, acdb_dev_id,
                                   sample_rate,
                                   usecase->type,
                                   usecase->type == PCM_PLAYBACK ? usecase->out_snd_device :
                                                                   usecase->in_snd_device);
    return 0;
}

int audio_extn_utils_send_app_type_gain(struct audio_device *adev,
                                        int app_type,
                                        int *gain)
{
    int gain_cfg[4];
    const char *mixer_ctl_name = "App Type Gain";
    struct mixer_ctl *ctl;
    ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
    if (!ctl) {
        ALOGE("%s: Could not get volume ctl mixer %s", __func__,
              mixer_ctl_name);
        return -EINVAL;
    }
    gain_cfg[0] = 0;
    gain_cfg[1] = app_type;
    gain_cfg[2] = gain[0];
    gain_cfg[3] = gain[1];
    ALOGV("%s app_type %d l(%d) r(%d)", __func__,  app_type, gain[0], gain[1]);
    return mixer_ctl_set_array(ctl, gain_cfg,
                               sizeof(gain_cfg)/sizeof(gain_cfg[0]));
}

// this assumes correct app_type and sample_rate fields
// have been set for the stream using audio_extn_utils_send_app_type_cfg
void audio_extn_utils_send_audio_calibration(struct audio_device *adev,
                                             struct audio_usecase *usecase)
{
    int type = usecase->type;
    int app_type = 0;

    if (type == PCM_PLAYBACK && usecase->stream.out != NULL) {
        struct stream_out *out = usecase->stream.out;
        ALOGV("%s send cal for app_type %d, rate %d", __func__,
              out->app_type_cfg.app_type,
              out->app_type_cfg.sample_rate);
        platform_send_audio_calibration_v2(adev->platform, usecase,
                                           out->app_type_cfg.app_type,
                                           out->app_type_cfg.sample_rate);
    } else if (type == PCM_CAPTURE && usecase->stream.in != NULL) {
        struct stream_in *in = usecase->stream.in;
        ALOGV("%s send cal for capture app_type %d, rate %d", __func__,
              in->app_type_cfg.app_type,
              in->app_type_cfg.sample_rate);
        platform_send_audio_calibration_v2(adev->platform, usecase,
                                           in->app_type_cfg.app_type,
                                           in->app_type_cfg.sample_rate);
    } else {
        /* when app type is default. the sample rate is not used to send cal */
        platform_get_default_app_type_v2(adev->platform, type, &app_type);
        platform_send_audio_calibration_v2(adev->platform, usecase, app_type,
                                           48000);
    }
}

#define MAX_SND_CARD 8
#define RETRY_US 500000
#define RETRY_NUMBER 10

#define min(a, b) ((a) < (b) ? (a) : (b))

static const char *kConfigLocationList[] =
        {"/odm/etc", "/vendor/etc", "/system/etc"};
static const int kConfigLocationListSize =
        (sizeof(kConfigLocationList) / sizeof(kConfigLocationList[0]));

bool audio_extn_utils_resolve_config_file(char file_name[MIXER_PATH_MAX_LENGTH])
{
    char full_config_path[MIXER_PATH_MAX_LENGTH];
    for (int i = 0; i < kConfigLocationListSize; i++) {
        snprintf(full_config_path,
                 MIXER_PATH_MAX_LENGTH,
                 "%s/%s",
                 kConfigLocationList[i],
                 file_name);
        if (F_OK == access(full_config_path, 0)) {
            strcpy(file_name, full_config_path);
            return true;
        }
    }
    return false;
}

/* platform_info_file should be size 'MIXER_PATH_MAX_LENGTH' */
int audio_extn_utils_get_platform_info(const char* snd_card_name, char* platform_info_file)
{
    if (NULL == snd_card_name) {
        return -1;
    }

    struct snd_card_split *snd_split_handle = NULL;
    int ret = 0;
    audio_extn_set_snd_card_split(snd_card_name);
    snd_split_handle = audio_extn_get_snd_card_split();

    snprintf(platform_info_file, MIXER_PATH_MAX_LENGTH, "%s_%s_%s.xml",
                     PLATFORM_INFO_XML_BASE_STRING, snd_split_handle->snd_card,
                     snd_split_handle->form_factor);

    if (!audio_extn_utils_resolve_config_file(platform_info_file)) {
        memset(platform_info_file, 0, MIXER_PATH_MAX_LENGTH);
        snprintf(platform_info_file, MIXER_PATH_MAX_LENGTH, "%s_%s.xml",
                     PLATFORM_INFO_XML_BASE_STRING, snd_split_handle->snd_card);

        if (!audio_extn_utils_resolve_config_file(platform_info_file)) {
            memset(platform_info_file, 0, MIXER_PATH_MAX_LENGTH);
            strlcpy(platform_info_file, PLATFORM_INFO_XML_PATH, MIXER_PATH_MAX_LENGTH);
            ret = audio_extn_utils_resolve_config_file(platform_info_file) ? 0 : -1;
        }
    }

    return ret;
}

int audio_extn_utils_get_snd_card_num()
{

    void *hw_info = NULL;
    struct mixer *mixer = NULL;
    int retry_num = 0;
    int snd_card_num = 0;
    const char* snd_card_name = NULL;
    char platform_info_file[MIXER_PATH_MAX_LENGTH]= {0};

    struct acdb_platform_data *my_data = calloc(1, sizeof(struct acdb_platform_data));

    bool card_verifed[MAX_SND_CARD] = {0};
    const int retry_limit = property_get_int32("audio.snd_card.open.retries", RETRY_NUMBER);

    for (;;) {
        if (snd_card_num >= MAX_SND_CARD) {
            if (retry_num++ >= retry_limit) {
                ALOGE("%s: Unable to find correct sound card, aborting.", __func__);
                snd_card_num = -1;
                goto done;
            }

            snd_card_num = 0;
            usleep(RETRY_US);
            continue;
        }

        if (card_verifed[snd_card_num]) {
            ++snd_card_num;
            continue;
        }

        mixer = mixer_open(snd_card_num);

        if (!mixer) {
            ALOGE("%s: Unable to open the mixer card: %d", __func__,
               snd_card_num);
            ++snd_card_num;
            continue;
        }

        card_verifed[snd_card_num] = true;

        snd_card_name = mixer_get_name(mixer);
        hw_info = hw_info_init(snd_card_name);

        if (audio_extn_utils_get_platform_info(snd_card_name, platform_info_file) < 0) {
            ALOGE("Failed to find platform_info_file");
            goto cleanup;
        }

        /* Initialize snd card name specific ids and/or backends*/
        if (snd_card_info_init(platform_info_file, my_data,
                               &acdb_set_parameters) < 0) {
            ALOGE("Failed to find platform_info_file");
            goto cleanup;
        }

        /* validate the sound card name
         * my_data->snd_card_name can contain
         *     <a> complete sound card name, i.e. <device>-<codec>-<form_factor>-snd-card
         *         example: msm8994-tomtom-mtp-snd-card
         *     <b> or sub string of the card name, i.e. <device>-<codec>
         *         example: msm8994-tomtom
         * snd_card_name is truncated to 32 charaters as per mixer_get_name() implementation
         * so use min of my_data->snd_card_name and snd_card_name length for comparison
         */

        if (my_data->snd_card_name != NULL &&
                strncmp(snd_card_name, my_data->snd_card_name,
                        min(strlen(snd_card_name), strlen(my_data->snd_card_name))) != 0) {
            ALOGI("%s: found valid sound card %s, but not primary sound card %s",
                   __func__, snd_card_name, my_data->snd_card_name);
            goto cleanup;
        }

        ALOGI("%s: found sound card %s, primary sound card expected is %s",
              __func__, snd_card_name, my_data->snd_card_name);
        break;
  cleanup:
        ++snd_card_num;
        mixer_close(mixer);
        mixer = NULL;
        hw_info_deinit(hw_info);
        hw_info = NULL;
    }

done:
    mixer_close(mixer);
    hw_info_deinit(hw_info);

    if (my_data)
        free(my_data);

    return snd_card_num;
}
