/*
 * Copyright (C) 2020 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.
 */

#include "AudioTypes.h"
#include "StringUtils.h"
#include <media/TypeConverter.h> // requires libmedia_helper to get the Audio code.

namespace android::mediametrics::types {

const std::unordered_map<std::string, int32_t>& getAudioCallerNameMap() {
    // DO NOT MODIFY VALUES (OK to add new ones).
    // This may be found in frameworks/av/media/libmediametrics/include/MediaMetricsConstants.h
    static std::unordered_map<std::string, int32_t> map{
        {"unknown",       0},           // callerName not set
        {"aaudio",        1},           // Native AAudio
        {"java",          2},           // Java API layer
        {"media",         3},           // libmedia (mediaplayer)
        {"opensles",      4},           // Open SLES
        {"rtp",           5},           // RTP communication
        {"soundpool",     6},           // SoundPool
        {"tonegenerator", 7},           // dial tones
        // R values above.
    };
    return map;
}

// A map in case we need to return a flag for input devices.
// This is 64 bits (and hence not the same as audio_device_t) because we need extra
// bits to represent new devices.
// NOT USED FOR R.  We do not use int64 flags.
// This can be out of date for now, as it is unused even for string validation
// (instead TypeConverter<InputDeviceTraits> is used).
const std::unordered_map<std::string, int64_t>& getAudioDeviceInMap() {
    // DO NOT MODIFY VALUES (OK to add new ones).  This does NOT match audio_device_t.
    static std::unordered_map<std::string, int64_t> map{
        {"AUDIO_DEVICE_IN_COMMUNICATION",          1LL << 0},
        {"AUDIO_DEVICE_IN_AMBIENT",                1LL << 1},
        {"AUDIO_DEVICE_IN_BUILTIN_MIC",            1LL << 2},
        {"AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET",  1LL << 3},
        {"AUDIO_DEVICE_IN_WIRED_HEADSET",          1LL << 4},
        {"AUDIO_DEVICE_IN_AUX_DIGITAL",            1LL << 5},
        {"AUDIO_DEVICE_IN_HDMI",                   1LL << 5}, // HDMI == AUX_DIGITAL (6 reserved)
        {"AUDIO_DEVICE_IN_VOICE_CALL",             1LL << 7},
        {"AUDIO_DEVICE_IN_TELEPHONY_RX",           1LL << 7}, // TELEPHONY_RX == VOICE_CALL (8 reserved)
        {"AUDIO_DEVICE_IN_BACK_MIC",               1LL << 9},
        {"AUDIO_DEVICE_IN_REMOTE_SUBMIX",          1LL << 10},
        {"AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET",      1LL << 11},
        {"AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET",      1LL << 12},
        {"AUDIO_DEVICE_IN_USB_ACCESSORY",          1LL << 13},
        {"AUDIO_DEVICE_IN_USB_DEVICE",             1LL << 14},
        {"AUDIO_DEVICE_IN_FM_TUNER",               1LL << 15},
        {"AUDIO_DEVICE_IN_TV_TUNER",               1LL << 16},
        {"AUDIO_DEVICE_IN_LINE",                   1LL << 17},
        {"AUDIO_DEVICE_IN_SPDIF",                  1LL << 18},
        {"AUDIO_DEVICE_IN_BLUETOOTH_A2DP",         1LL << 19},
        {"AUDIO_DEVICE_IN_LOOPBACK",               1LL << 20},
        {"AUDIO_DEVICE_IN_IP",                     1LL << 21},
        {"AUDIO_DEVICE_IN_BUS",                    1LL << 22},
        {"AUDIO_DEVICE_IN_PROXY",                  1LL << 23},
        {"AUDIO_DEVICE_IN_USB_HEADSET",            1LL << 24},
        {"AUDIO_DEVICE_IN_BLUETOOTH_BLE",          1LL << 25},
        {"AUDIO_DEVICE_IN_HDMI_ARC",               1LL << 26},
        {"AUDIO_DEVICE_IN_ECHO_REFERENCE",         1LL << 27},
        {"AUDIO_DEVICE_IN_DEFAULT",                1LL << 28},
        // R values above.
        {"AUDIO_DEVICE_IN_BLE_HEADSET",            1LL << 29},
        {"AUDIO_DEVICE_IN_HDMI_EARC",              1LL << 30},
    };
    return map;
}

// A map in case we need to return a flag for output devices.
// This is 64 bits (and hence not the same as audio_device_t) because we need extra
// bits to represent new devices.
// NOT USED FOR R.  We do not use int64 flags.
// This can be out of date for now, as it is unused even for string validation
// (instead TypeConverter<OutputDeviceTraits> is used).
const std::unordered_map<std::string, int64_t>& getAudioDeviceOutMap() {
    // DO NOT MODIFY VALUES (OK to add new ones).  This does NOT match audio_device_t.
    static std::unordered_map<std::string, int64_t> map{
        {"AUDIO_DEVICE_OUT_EARPIECE",                  1LL << 0},
        {"AUDIO_DEVICE_OUT_SPEAKER",                   1LL << 1},
        {"AUDIO_DEVICE_OUT_WIRED_HEADSET",             1LL << 2},
        {"AUDIO_DEVICE_OUT_WIRED_HEADPHONE",           1LL << 3},
        {"AUDIO_DEVICE_OUT_BLUETOOTH_SCO",             1LL << 4},
        {"AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET",     1LL << 5},
        {"AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT",      1LL << 6},
        {"AUDIO_DEVICE_OUT_BLUETOOTH_A2DP",            1LL << 7},
        {"AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES", 1LL << 8},
        {"AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER",    1LL << 9},
        {"AUDIO_DEVICE_OUT_AUX_DIGITAL",               1LL << 10},
        {"AUDIO_DEVICE_OUT_HDMI",                      1LL << 10}, // HDMI == AUX_DIGITAL (11 reserved)
        {"AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET",         1LL << 12},
        {"AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET",         1LL << 13},
        {"AUDIO_DEVICE_OUT_USB_ACCESSORY",             1LL << 14},
        {"AUDIO_DEVICE_OUT_USB_DEVICE",                1LL << 15},
        {"AUDIO_DEVICE_OUT_REMOTE_SUBMIX",             1LL << 16},
        {"AUDIO_DEVICE_OUT_TELEPHONY_TX",              1LL << 17},
        {"AUDIO_DEVICE_OUT_LINE",                      1LL << 18},
        {"AUDIO_DEVICE_OUT_HDMI_ARC",                  1LL << 19},
        {"AUDIO_DEVICE_OUT_SPDIF",                     1LL << 20},
        {"AUDIO_DEVICE_OUT_FM",                        1LL << 21},
        {"AUDIO_DEVICE_OUT_AUX_LINE",                  1LL << 22},
        {"AUDIO_DEVICE_OUT_SPEAKER_SAFE",              1LL << 23},
        {"AUDIO_DEVICE_OUT_IP",                        1LL << 24},
        {"AUDIO_DEVICE_OUT_BUS",                       1LL << 25},
        {"AUDIO_DEVICE_OUT_PROXY",                     1LL << 26},
        {"AUDIO_DEVICE_OUT_USB_HEADSET",               1LL << 27},
        {"AUDIO_DEVICE_OUT_HEARING_AID",               1LL << 28},
        {"AUDIO_DEVICE_OUT_ECHO_CANCELLER",            1LL << 29},
        {"AUDIO_DEVICE_OUT_DEFAULT",                   1LL << 30},
        // R values above.
        {"AUDIO_DEVICE_OUT_BLE_HEADSET",               1LL << 31},
        {"AUDIO_DEVICE_OUT_BLE_SPEAKER",               1LL << 32},
        {"AUDIO_DEVICE_OUT_HDMI_EARC",                 1LL << 33},
    };
    return map;
}

const std::unordered_map<std::string, int32_t>& getAudioThreadTypeMap() {
    // DO NOT MODIFY VALUES (OK to add new ones).
    // This may be found in frameworks/av/services/audioflinger/Threads.h
    static std::unordered_map<std::string, int32_t> map{
        // UNKNOWN is -1
        {"MIXER",         0},          // Thread class is MixerThread
        {"DIRECT",        1},          // Thread class is DirectOutputThread
        {"DUPLICATING",   2},          // Thread class is DuplicatingThread
        {"RECORD",        3},          // Thread class is RecordThread
        {"OFFLOAD",       4},          // Thread class is OffloadThread
        {"MMAP_PLAYBACK", 5},          // Thread class for MMAP playback stream
        {"MMAP_CAPTURE",  6},          // Thread class for MMAP capture stream
        // R values above.
    };
    return map;
}

const std::unordered_map<std::string, int32_t>& getAudioTrackTraitsMap() {
    // DO NOT MODIFY VALUES (OK to add new ones).
    static std::unordered_map<std::string, int32_t> map{
        {"static",        (1 << 0)},  // A static track
        // R values above.
    };
    return map;
}

const std::unordered_map<std::string, int32_t>& getAAudioDirection() {
    // DO NOT MODIFY VALUES(OK to add new ones).
    // This may be found in frameworks/av/media/libaaudio/include/aaudio/AAudio.h
    static std::unordered_map<std::string, int32_t> map {
        // UNKNOWN is 0
        {"AAUDIO_DIRECTION_OUTPUT",    1 /* AAUDIO_DIRECTION_OUTPUT + 1 */},
        {"AAUDIO_DIRECTION_INPUT",     2 /* AAUDIO_DIRECTION_INPUT + 1*/},
    };
    return map;
}

const std::unordered_map<std::string, int32_t>& getAAudioPerformanceMode() {
    // DO NOT MODIFY VALUES(OK to add new ones).
    // This may be found in frameworks/av/media/libaaudio/include/aaudio/AAudio.h
    static std::unordered_map<std::string, int32_t> map {
        // UNKNOWN is 0
        {"AAUDIO_PERFORMANCE_MODE_NONE",            10},
        {"AAUDIO_PERFORMANCE_MODE_POWER_SAVING",    11},
        {"AAUDIO_PERFORMANCE_MODE_LOW_LATENCY",     12},
    };
    return map;
}

const std::unordered_map<std::string, int32_t>& getAAudioSharingMode() {
    // DO NOT MODIFY VALUES(OK to add new ones).
    // This may be found in frameworks/av/media/libaaudio/include/aaudio/AAudio.h
    static std::unordered_map<std::string, int32_t> map {
        // UNKNOWN is 0
        {"AAUDIO_SHARING_MODE_EXCLUSIVE",    1 /* AAUDIO_SHARING_MODE_EXCLUSIVE + 1 */},
        {"AAUDIO_SHARING_MODE_SHARED",       2 /* AAUDIO_SHARING_MODE_SHARED + 1 */},
    };
    return map;
}

// Helper: Create the corresponding int32 from string flags split with '|'.
template <typename Traits>
int32_t int32FromFlags(const std::string &flags)
{
    const auto result = stringutils::split(flags, "|");
    int32_t intFlags = 0;
    for (const auto& flag : result) {
        typename Traits::Type value;
        if (!TypeConverter<Traits>::fromString(flag, value)) {
            break;
        }
        intFlags |= value;
    }
    return intFlags;
}

template <typename Traits>
std::string stringFromFlags(const std::string &flags, size_t len)
{
    const auto result = stringutils::split(flags, "|");
    std::string sFlags;
    for (const auto& flag : result) {
        typename Traits::Type value;
        if (!TypeConverter<Traits>::fromString(flag, value)) {
            break;
        }
        if (len >= flag.size()) continue;
        if (!sFlags.empty()) sFlags += "|";
        sFlags += flag.c_str() + len;
    }
    return sFlags;
}

template <typename M>
std::string validateStringFromMap(const std::string &str, const M& map)
{
    if (str.empty()) return {};

    const auto result = stringutils::split(str, "|");
    std::stringstream ss;
    for (const auto &s : result) {
        if (map.count(s) > 0) {
            if (ss.tellp() > 0) ss << "|";
            ss << s;
        }
    }
    return ss.str();
}

template <typename M>
typename M::mapped_type flagsFromMap(const std::string &str, const M& map)
{
    if (str.empty()) return {};

    const auto result = stringutils::split(str, "|");
    typename M::mapped_type value{};
    for (const auto &s : result) {
        auto it = map.find(s);
        if (it == map.end()) continue;
        value |= it->second;
    }
    return value;
}

template <>
int32_t lookup<CONTENT_TYPE>(const std::string &contentType)
{
    AudioContentTraits::Type value;
    if (!TypeConverter<AudioContentTraits>::fromString(contentType, value)) {
        value = AUDIO_CONTENT_TYPE_UNKNOWN;
    }
    return (int32_t)value;
}

template <>
std::string lookup<CONTENT_TYPE>(const std::string &contentType)
{
    AudioContentTraits::Type value;
    if (!TypeConverter<AudioContentTraits>::fromString(contentType, value)) {
        return "";
    }
    return contentType.c_str() + sizeof("AUDIO_CONTENT_TYPE");
}

template <>
int32_t lookup<ENCODING>(const std::string &encoding)
{
    FormatTraits::Type value;
    if (!TypeConverter<FormatTraits>::fromString(encoding, value)) {
        value = AUDIO_FORMAT_INVALID;
    }
    return (int32_t)value;
}

template <>
std::string lookup<ENCODING>(const std::string &encoding)
{
    FormatTraits::Type value;
    if (!TypeConverter<FormatTraits>::fromString(encoding, value)) {
        return "";
    }
    return encoding.c_str() + sizeof("AUDIO_FORMAT");
}

template <>
int32_t lookup<INPUT_FLAG>(const std::string &inputFlag)
{
    return int32FromFlags<InputFlagTraits>(inputFlag);
}

template <>
std::string lookup<INPUT_FLAG>(const std::string &inputFlag)
{
    return stringFromFlags<InputFlagTraits>(inputFlag, sizeof("AUDIO_INPUT_FLAG"));
}

template <>
int32_t lookup<OUTPUT_FLAG>(const std::string &outputFlag)
{
    return int32FromFlags<OutputFlagTraits>(outputFlag);
}

template <>
std::string lookup<OUTPUT_FLAG>(const std::string &outputFlag)
{
    return stringFromFlags<OutputFlagTraits>(outputFlag, sizeof("AUDIO_OUTPUT_FLAG"));
}

template <>
int32_t lookup<SOURCE_TYPE>(const std::string &sourceType)
{
    SourceTraits::Type value;
    if (!TypeConverter<SourceTraits>::fromString(sourceType, value)) {
        value = AUDIO_SOURCE_DEFAULT;
    }
    return (int32_t)value;
}

template <>
std::string lookup<SOURCE_TYPE>(const std::string &sourceType)
{
    SourceTraits::Type value;
    if (!TypeConverter<SourceTraits>::fromString(sourceType, value)) {
        return "";
    }
    return sourceType.c_str() + sizeof("AUDIO_SOURCE");
}

template <>
int32_t lookup<STREAM_TYPE>(const std::string &streamType)
{
    StreamTraits::Type value;
    if (!TypeConverter<StreamTraits>::fromString(streamType, value)) {
        value = AUDIO_STREAM_DEFAULT;
    }
    return (int32_t)value;
}

template <>
std::string lookup<STREAM_TYPE>(const std::string &streamType)
{
    StreamTraits::Type value;
    if (!TypeConverter<StreamTraits>::fromString(streamType, value)) {
        return "";
    }
    return streamType.c_str() + sizeof("AUDIO_STREAM");
}

template <>
int32_t lookup<USAGE>(const std::string &usage)
{
    UsageTraits::Type value;
    if (!TypeConverter<UsageTraits>::fromString(usage, value)) {
        value = AUDIO_USAGE_UNKNOWN;
    }
    return (int32_t)value;
}

template <>
std::string lookup<USAGE>(const std::string &usage)
{
    UsageTraits::Type value;
    if (!TypeConverter<UsageTraits>::fromString(usage, value)) {
        return "";
    }
    return usage.c_str() + sizeof("AUDIO_USAGE");
}

template <>
int64_t lookup<INPUT_DEVICE>(const std::string &inputDevice)
{
    // NOT USED FOR R.
    // Returns a set of bits, each one representing a device in inputDevice.
    // This is a 64 bit integer, not the same as audio_device_t.
    return flagsFromMap(inputDevice, getAudioDeviceInMap());
}

template <>
std::string lookup<INPUT_DEVICE>(const std::string &inputDevice)
{
    return stringFromFlags<InputDeviceTraits>(inputDevice, sizeof("AUDIO_DEVICE_IN"));
}

template <>
int64_t lookup<OUTPUT_DEVICE>(const std::string &outputDevice)
{
    // NOT USED FOR R.
    // Returns a set of bits, each one representing a device in outputDevice.
    // This is a 64 bit integer, not the same as audio_device_t.
    return flagsFromMap(outputDevice, getAudioDeviceOutMap());
}

template <>
std::string lookup<OUTPUT_DEVICE>(const std::string &outputDevice)
{
    return stringFromFlags<OutputDeviceTraits>(outputDevice, sizeof("AUDIO_DEVICE_OUT"));
}

template <>
int32_t lookup<CALLER_NAME>(const std::string &callerName)
{
    auto& map = getAudioCallerNameMap();
    auto it = map.find(callerName);
    if (it == map.end()) {
        return 0;      // return unknown
    }
    return it->second;
}

template <>
std::string lookup<CALLER_NAME>(const std::string &callerName)
{
    auto& map = getAudioCallerNameMap();
    auto it = map.find(callerName);
    if (it == map.end()) {
        return "";
    }
    return callerName;
}

template <>
int32_t lookup<THREAD_TYPE>(const std::string &threadType)
{
    auto& map = getAudioThreadTypeMap();
    auto it = map.find(threadType);
    if (it == map.end()) {
        return -1; // note this as an illegal thread value as we don't have unknown here.
    }
    return it->second;
}

template <>
std::string lookup<THREAD_TYPE>(const std::string &threadType)
{
    auto& map = getAudioThreadTypeMap();
    auto it = map.find(threadType);
    if (it == map.end()) {
        return "";
    }
    return threadType;
}

bool isInputThreadType(const std::string &threadType)
{
    return threadType == "RECORD" || threadType == "MMAP_CAPTURE";
}

template <>
std::string lookup<TRACK_TRAITS>(const std::string &traits)
{
    return validateStringFromMap(traits, getAudioTrackTraitsMap());
}

template <>
int32_t lookup<TRACK_TRAITS>(const std::string &traits)
{
    return flagsFromMap(traits, getAudioTrackTraitsMap());
}

template <>
std::string lookup<AAUDIO_DIRECTION>(const std::string &direction)
{
    auto& map = getAAudioDirection();
    auto it = map.find(direction);
    if (it == map.end()) {
        return "";
    }
    return direction;
}

template <>
int32_t lookup<AAUDIO_DIRECTION>(const std::string &direction)
{
    auto& map = getAAudioDirection();
    auto it = map.find(direction);
    if (it == map.end()) {
        return 0; // return unknown
    }
    return it->second;
}

template <>
std::string lookup<AAUDIO_PERFORMANCE_MODE>(const std::string &performanceMode)
{
    auto& map = getAAudioPerformanceMode();
    auto it = map.find(performanceMode);
    if (it == map.end()) {
        return "";
    }
    return performanceMode;
}

template <>
int32_t lookup<AAUDIO_PERFORMANCE_MODE>(const std::string &performanceMode)
{
    auto& map = getAAudioPerformanceMode();
    auto it = map.find(performanceMode);
    if (it == map.end()) {
        return 0; // return unknown
    }
    return it->second;
}

template <>
std::string lookup<AAUDIO_SHARING_MODE>(const std::string &sharingMode)
{
    auto& map = getAAudioSharingMode();
    auto it = map.find(sharingMode);
    if (it == map.end()) {
        return "";
    }
    return sharingMode;
}

template <>
int32_t lookup<AAUDIO_SHARING_MODE>(const std::string &sharingMode)
{
    auto& map = getAAudioSharingMode();
    auto it = map.find(sharingMode);
    if (it == map.end()) {
        return 0; // return unknown
    }
    return it->second;
}

} // namespace android::mediametrics::types
