/*
 * Copyright (C) 2024 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 <inttypes.h>

#include <unordered_set>

#define LOG_TAG "AHAL_Config"
#include <android-base/logging.h>
#include <android-base/strings.h>
#include <android/binder_enums.h>

#include <aidl/android/media/audio/common/AudioPort.h>
#include <aidl/android/media/audio/common/AudioPortConfig.h>
#include <media/AidlConversionCppNdk.h>
#include <media/TypeConverter.h>
#include <media/convert.h>
#include <utils/FastStrcmp.h>

#include <Utils.h>

#include "core-impl/XmlConverter.h"
#include "core-impl/XsdcConversion.h"

using aidl::android::hardware::audio::common::iequals;
using aidl::android::hardware::audio::common::isValidAudioMode;
using aidl::android::hardware::audio::common::kValidAudioModes;
using aidl::android::media::audio::common::AudioChannelLayout;
using aidl::android::media::audio::common::AudioContentType;
using aidl::android::media::audio::common::AudioDevice;
using aidl::android::media::audio::common::AudioDeviceAddress;
using aidl::android::media::audio::common::AudioDeviceDescription;
using aidl::android::media::audio::common::AudioDeviceType;
using aidl::android::media::audio::common::AudioFormatDescription;
using aidl::android::media::audio::common::AudioFormatType;
using aidl::android::media::audio::common::AudioGain;
using aidl::android::media::audio::common::AudioHalCapCriterion;
using aidl::android::media::audio::common::AudioHalCapCriterionType;
using aidl::android::media::audio::common::AudioHalCapCriterionV2;
using aidl::android::media::audio::common::AudioHalVolumeCurve;
using aidl::android::media::audio::common::AudioIoFlags;
using aidl::android::media::audio::common::AudioMode;
using aidl::android::media::audio::common::AudioPolicyForceUse;
using aidl::android::media::audio::common::AudioPort;
using aidl::android::media::audio::common::AudioPortConfig;
using aidl::android::media::audio::common::AudioPortDeviceExt;
using aidl::android::media::audio::common::AudioPortExt;
using aidl::android::media::audio::common::AudioPortMixExt;
using aidl::android::media::audio::common::AudioProfile;
using aidl::android::media::audio::common::AudioSource;
using aidl::android::media::audio::common::AudioStreamType;
using aidl::android::media::audio::common::AudioUsage;
using android::BAD_VALUE;
using android::base::unexpected;
using android::utilities::convertTo;
using ndk::enum_range;

namespace ap_xsd = android::audio::policy::configuration;
namespace eng_xsd = android::audio::policy::engine::configuration;

namespace aidl::android::hardware::audio::core::internal {

static constexpr const char kXsdcForceConfigForCommunication[] = "ForceUseForCommunication";
static constexpr const char kXsdcForceConfigForMedia[] = "ForceUseForMedia";
static constexpr const char kXsdcForceConfigForRecord[] = "ForceUseForRecord";
static constexpr const char kXsdcForceConfigForDock[] = "ForceUseForDock";
static constexpr const char kXsdcForceConfigForSystem[] = "ForceUseForSystem";
static constexpr const char kXsdcForceConfigForHdmiSystemAudio[] = "ForceUseForHdmiSystemAudio";
static constexpr const char kXsdcForceConfigForEncodedSurround[] = "ForceUseForEncodedSurround";
static constexpr const char kXsdcForceConfigForVibrateRinging[] = "ForceUseForVibrateRinging";

inline ConversionResult<std::string> assertNonEmpty(const std::string& s) {
    if (s.empty()) {
        LOG(ERROR) << __func__ << " Review Audio Policy config: "
                   << " empty string is not valid.";
        return unexpected(BAD_VALUE);
    }
    return s;
}

#define NON_EMPTY_STRING_OR_FATAL(s) VALUE_OR_FATAL(assertNonEmpty(s))

ConversionResult<int32_t> convertAudioFlagsToAidl(
        const std::vector<eng_xsd::FlagType>& xsdcFlagTypeVec) {
    int legacyFlagMask = 0;
    for (const eng_xsd::FlagType& xsdcFlagType : xsdcFlagTypeVec) {
        if (xsdcFlagType != eng_xsd::FlagType::AUDIO_FLAG_NONE) {
            audio_flags_mask_t legacyFlag = AUDIO_FLAG_NONE;
            if (!::android::AudioFlagConverter::fromString(eng_xsd::toString(xsdcFlagType),
                                                           legacyFlag)) {
                LOG(ERROR) << __func__ << " Review Audio Policy config, "
                           << eng_xsd::toString(xsdcFlagType) << " is not a valid flag.";
                return unexpected(BAD_VALUE);
            }
            legacyFlagMask |= static_cast<int>(legacyFlag);
        }
    }
    ConversionResult<int32_t> result = legacy2aidl_audio_flags_mask_t_int32_t_mask(
            static_cast<audio_flags_mask_t>(legacyFlagMask));
    if (!result.ok()) {
        LOG(ERROR) << __func__ << " Review Audio Policy config, " << legacyFlagMask
                   << " has invalid flag(s).";
        return unexpected(BAD_VALUE);
    }
    return result;
}

ConversionResult<AudioStreamType> convertAudioStreamTypeToAidl(const eng_xsd::Stream& xsdcStream) {
    audio_stream_type_t legacyStreamType;
    if (!::android::StreamTypeConverter::fromString(eng_xsd::toString(xsdcStream),
                                                    legacyStreamType)) {
        LOG(ERROR) << __func__ << " Review Audio Policy config, " << eng_xsd::toString(xsdcStream)
                   << " is not a valid audio stream type.";
        return unexpected(BAD_VALUE);
    }
    ConversionResult<AudioStreamType> result =
            legacy2aidl_audio_stream_type_t_AudioStreamType(legacyStreamType);
    if (!result.ok()) {
        LOG(ERROR) << __func__ << " Review Audio Policy config, " << legacyStreamType
                   << " is not a valid audio stream type.";
        return unexpected(BAD_VALUE);
    }
    return result;
}

ConversionResult<AudioSource> convertAudioSourceToAidl(
        const eng_xsd::SourceEnumType& xsdcSourceType) {
    audio_source_t legacySourceType;
    if (!::android::SourceTypeConverter::fromString(eng_xsd::toString(xsdcSourceType),
                                                    legacySourceType)) {
        LOG(ERROR) << __func__ << " Review Audio Policy config, "
                   << eng_xsd::toString(xsdcSourceType) << " is not a valid audio source.";
        return unexpected(BAD_VALUE);
    }
    ConversionResult<AudioSource> result = legacy2aidl_audio_source_t_AudioSource(legacySourceType);
    if (!result.ok()) {
        LOG(ERROR) << __func__ << " Review Audio Policy config, " << legacySourceType
                   << " is not a valid audio source.";
        return unexpected(BAD_VALUE);
    }
    return result;
}

ConversionResult<AudioContentType> convertAudioContentTypeToAidl(
        const eng_xsd::ContentType& xsdcContentType) {
    audio_content_type_t legacyContentType;
    if (!::android::AudioContentTypeConverter::fromString(eng_xsd::toString(xsdcContentType),
                                                          legacyContentType)) {
        LOG(ERROR) << __func__ << " Review Audio Policy config, "
                   << eng_xsd::toString(xsdcContentType) << " is not a valid audio content type.";
        return unexpected(BAD_VALUE);
    }
    ConversionResult<AudioContentType> result =
            legacy2aidl_audio_content_type_t_AudioContentType(legacyContentType);
    if (!result.ok()) {
        LOG(ERROR) << __func__ << " Review Audio Policy config, " << legacyContentType
                   << " is not a valid audio content type.";
        return unexpected(BAD_VALUE);
    }
    return result;
}

ConversionResult<AudioUsage> convertAudioUsageToAidl(const eng_xsd::UsageEnumType& xsdcUsage) {
    audio_usage_t legacyUsage;
    if (!::android::UsageTypeConverter::fromString(eng_xsd::toString(xsdcUsage), legacyUsage)) {
        LOG(ERROR) << __func__ << " Review Audio Policy config, not a valid audio usage.";
        return unexpected(BAD_VALUE);
    }
    ConversionResult<AudioUsage> result = legacy2aidl_audio_usage_t_AudioUsage(legacyUsage);
    if (!result.ok()) {
        LOG(ERROR) << __func__ << " Review Audio Policy config, not a valid audio usage.";
        return unexpected(BAD_VALUE);
    }
    return result;
}

ConversionResult<AudioFormatDescription> convertAudioFormatToAidl(const std::string& xsdcFormat) {
    audio_format_t legacyFormat = ::android::formatFromString(xsdcFormat, AUDIO_FORMAT_DEFAULT);
    ConversionResult<AudioFormatDescription> result =
            legacy2aidl_audio_format_t_AudioFormatDescription(legacyFormat);
    if ((legacyFormat == AUDIO_FORMAT_DEFAULT && xsdcFormat.compare("AUDIO_FORMAT_DEFAULT") != 0) ||
        !result.ok()) {
        LOG(ERROR) << __func__ << " Review Audio Policy config: " << xsdcFormat
                   << " is not a valid audio format.";
        return unexpected(BAD_VALUE);
    }
    return result;
}

std::unordered_set<std::string> getAttachedDevices(const ap_xsd::Modules::Module& moduleConfig) {
    std::unordered_set<std::string> attachedDeviceSet;
    if (moduleConfig.hasAttachedDevices()) {
        for (const ap_xsd::AttachedDevices& attachedDevices : moduleConfig.getAttachedDevices()) {
            if (attachedDevices.hasItem()) {
                attachedDeviceSet.insert(attachedDevices.getItem().begin(),
                                         attachedDevices.getItem().end());
            }
        }
    }
    return attachedDeviceSet;
}

ConversionResult<AudioDeviceDescription> convertDeviceTypeToAidl(const std::string& xType) {
    audio_devices_t legacyDeviceType = AUDIO_DEVICE_NONE;
    ::android::DeviceConverter::fromString(xType, legacyDeviceType);
    ConversionResult<AudioDeviceDescription> result =
            legacy2aidl_audio_devices_t_AudioDeviceDescription(legacyDeviceType);
    if ((legacyDeviceType == AUDIO_DEVICE_NONE) || !result.ok()) {
        LOG(ERROR) << __func__ << " Review Audio Policy config: " << xType
                   << " is not a valid device type.";
        return unexpected(BAD_VALUE);
    }
    return result;
}

ConversionResult<AudioDevice> createAudioDevice(
        const ap_xsd::DevicePorts::DevicePort& xDevicePort) {
    AudioDevice device = {
            .type = VALUE_OR_FATAL(convertDeviceTypeToAidl(xDevicePort.getType())),
            .address = xDevicePort.hasAddress()
                               ? AudioDeviceAddress::make<AudioDeviceAddress::Tag::id>(
                                         xDevicePort.getAddress())
                               : AudioDeviceAddress{}};
    if (device.type.type == AudioDeviceType::IN_MICROPHONE && device.type.connection.empty()) {
        device.address = "bottom";
    } else if (device.type.type == AudioDeviceType::IN_MICROPHONE_BACK &&
               device.type.connection.empty()) {
        device.address = "back";
    }
    return device;
}

ConversionResult<AudioPortExt> createAudioPortExt(
        const ap_xsd::DevicePorts::DevicePort& xDevicePort,
        const std::string& xDefaultOutputDevice) {
    AudioPortDeviceExt deviceExt = {
            .device = VALUE_OR_FATAL(createAudioDevice(xDevicePort)),
            .flags = (xDevicePort.getTagName() == xDefaultOutputDevice)
                             ? 1 << AudioPortDeviceExt::FLAG_INDEX_DEFAULT_DEVICE
                             : 0,
            .encodedFormats =
                    xDevicePort.hasEncodedFormats()
                            ? VALUE_OR_FATAL(
                                      (convertCollectionToAidl<std::string, AudioFormatDescription>(
                                              xDevicePort.getEncodedFormats(),
                                              &convertAudioFormatToAidl)))
                            : std::vector<AudioFormatDescription>{},
    };
    return AudioPortExt::make<AudioPortExt::Tag::device>(deviceExt);
}

ConversionResult<AudioPortExt> createAudioPortExt(const ap_xsd::MixPorts::MixPort& xMixPort) {
    AudioPortMixExt mixExt = {
            .maxOpenStreamCount =
                    xMixPort.hasMaxOpenCount() ? static_cast<int>(xMixPort.getMaxOpenCount()) : 0,
            .maxActiveStreamCount = xMixPort.hasMaxActiveCount()
                                            ? static_cast<int>(xMixPort.getMaxActiveCount())
                                            : 1,
            .recommendedMuteDurationMs =
                    xMixPort.hasRecommendedMuteDurationMs()
                            ? static_cast<int>(xMixPort.getRecommendedMuteDurationMs())
                            : 0};
    return AudioPortExt::make<AudioPortExt::Tag::mix>(mixExt);
}

ConversionResult<int> convertGainModeToAidl(const std::vector<ap_xsd::AudioGainMode>& gainModeVec) {
    int gainModeMask = 0;
    for (const ap_xsd::AudioGainMode& gainMode : gainModeVec) {
        audio_gain_mode_t legacyGainMode;
        if (::android::GainModeConverter::fromString(ap_xsd::toString(gainMode), legacyGainMode)) {
            gainModeMask |= static_cast<int>(legacyGainMode);
        }
    }
    return gainModeMask;
}

ConversionResult<AudioChannelLayout> convertChannelMaskToAidl(
        const ap_xsd::AudioChannelMask& xChannelMask) {
    std::string xChannelMaskLiteral = ap_xsd::toString(xChannelMask);
    audio_channel_mask_t legacyChannelMask = ::android::channelMaskFromString(xChannelMaskLiteral);
    ConversionResult<AudioChannelLayout> result =
            legacy2aidl_audio_channel_mask_t_AudioChannelLayout(
                    legacyChannelMask,
                    /* isInput= */ xChannelMaskLiteral.find("AUDIO_CHANNEL_IN_") == 0);
    if ((legacyChannelMask == AUDIO_CHANNEL_INVALID) || !result.ok()) {
        LOG(ERROR) << __func__ << " Review Audio Policy config: " << xChannelMaskLiteral
                   << " is not a valid audio channel mask.";
        return unexpected(BAD_VALUE);
    }
    return result;
}

ConversionResult<AudioGain> convertGainToAidl(const ap_xsd::Gains::Gain& xGain) {
    return AudioGain{
            .mode = VALUE_OR_FATAL(convertGainModeToAidl(xGain.getMode())),
            .channelMask =
                    xGain.hasChannel_mask()
                            ? VALUE_OR_FATAL(convertChannelMaskToAidl(xGain.getChannel_mask()))
                            : AudioChannelLayout{},
            .minValue = xGain.hasMinValueMB() ? xGain.getMinValueMB() : 0,
            .maxValue = xGain.hasMaxValueMB() ? xGain.getMaxValueMB() : 0,
            .defaultValue = xGain.hasDefaultValueMB() ? xGain.getDefaultValueMB() : 0,
            .stepValue = xGain.hasStepValueMB() ? xGain.getStepValueMB() : 0,
            .minRampMs = xGain.hasMinRampMs() ? xGain.getMinRampMs() : 0,
            .maxRampMs = xGain.hasMaxRampMs() ? xGain.getMaxRampMs() : 0,
            .useForVolume = xGain.hasUseForVolume() ? xGain.getUseForVolume() : false,
    };
}

ConversionResult<AudioProfile> convertAudioProfileToAidl(const ap_xsd::Profile& xProfile) {
    return AudioProfile{
            .format = xProfile.hasFormat()
                              ? VALUE_OR_FATAL(convertAudioFormatToAidl(xProfile.getFormat()))
                              : AudioFormatDescription{},
            .channelMasks =
                    xProfile.hasChannelMasks()
                            ? VALUE_OR_FATAL((convertCollectionToAidl<ap_xsd::AudioChannelMask,
                                                                      AudioChannelLayout>(
                                      xProfile.getChannelMasks(), &convertChannelMaskToAidl)))
                            : std::vector<AudioChannelLayout>{},
            .sampleRates = xProfile.hasSamplingRates()
                                   ? VALUE_OR_FATAL((convertCollectionToAidl<int64_t, int>(
                                             xProfile.getSamplingRates(),
                                             [](const int64_t x) -> int { return x; })))
                                   : std::vector<int>{}};
}

ConversionResult<AudioIoFlags> convertIoFlagsToAidl(
        const std::vector<ap_xsd::AudioInOutFlag>& flags, const ap_xsd::Role role,
        bool flagsForMixPort) {
    int legacyFlagMask = 0;
    if ((role == ap_xsd::Role::sink && flagsForMixPort) ||
        (role == ap_xsd::Role::source && !flagsForMixPort)) {
        for (const ap_xsd::AudioInOutFlag& flag : flags) {
            audio_input_flags_t legacyFlag;
            if (::android::InputFlagConverter::fromString(ap_xsd::toString(flag), legacyFlag)) {
                legacyFlagMask |= static_cast<int>(legacyFlag);
            }
        }
        return AudioIoFlags::make<AudioIoFlags::Tag::input>(
                VALUE_OR_FATAL(legacy2aidl_audio_input_flags_t_int32_t_mask(
                        static_cast<audio_input_flags_t>(legacyFlagMask))));
    } else {
        for (const ap_xsd::AudioInOutFlag& flag : flags) {
            audio_output_flags_t legacyFlag;
            if (::android::OutputFlagConverter::fromString(ap_xsd::toString(flag), legacyFlag)) {
                legacyFlagMask |= static_cast<int>(legacyFlag);
            }
        }
        return AudioIoFlags::make<AudioIoFlags::Tag::output>(
                VALUE_OR_FATAL(legacy2aidl_audio_output_flags_t_int32_t_mask(
                        static_cast<audio_output_flags_t>(legacyFlagMask))));
    }
}

ConversionResult<AudioPort> convertDevicePortToAidl(
        const ap_xsd::DevicePorts::DevicePort& xDevicePort, const std::string& xDefaultOutputDevice,
        int32_t& nextPortId) {
    return AudioPort{
            .id = nextPortId++,
            .name = NON_EMPTY_STRING_OR_FATAL(xDevicePort.getTagName()),
            .profiles = VALUE_OR_FATAL((convertCollectionToAidl<ap_xsd::Profile, AudioProfile>(
                    xDevicePort.getProfile(), convertAudioProfileToAidl))),
            .flags = VALUE_OR_FATAL(convertIoFlagsToAidl({}, xDevicePort.getRole(), false)),
            .gains = VALUE_OR_FATAL(
                    (convertWrappedCollectionToAidl<ap_xsd::Gains, ap_xsd::Gains::Gain, AudioGain>(
                            xDevicePort.getGains(), &ap_xsd::Gains::getGain, convertGainToAidl))),

            .ext = VALUE_OR_FATAL(createAudioPortExt(xDevicePort, xDefaultOutputDevice))};
}

ConversionResult<std::vector<AudioPort>> convertDevicePortsInModuleToAidl(
        const ap_xsd::Modules::Module& xModuleConfig, int32_t& nextPortId) {
    std::vector<AudioPort> audioPortVec;
    std::vector<ap_xsd::DevicePorts> xDevicePortsVec = xModuleConfig.getDevicePorts();
    if (xDevicePortsVec.size() > 1) {
        LOG(ERROR) << __func__ << "Having multiple '<devicePorts>' elements is not allowed, found: "
                   << xDevicePortsVec.size();
        return unexpected(BAD_VALUE);
    }
    if (!xDevicePortsVec.empty()) {
        const std::string xDefaultOutputDevice = xModuleConfig.hasDefaultOutputDevice()
                                                         ? xModuleConfig.getDefaultOutputDevice()
                                                         : "";
        audioPortVec.reserve(xDevicePortsVec[0].getDevicePort().size());
        for (const ap_xsd::DevicePorts& xDevicePortsType : xDevicePortsVec) {
            for (const ap_xsd::DevicePorts::DevicePort& xDevicePort :
                 xDevicePortsType.getDevicePort()) {
                audioPortVec.push_back(VALUE_OR_FATAL(
                        convertDevicePortToAidl(xDevicePort, xDefaultOutputDevice, nextPortId)));
            }
        }
    }
    const std::unordered_set<std::string> xAttachedDeviceSet = getAttachedDevices(xModuleConfig);
    for (const auto& port : audioPortVec) {
        const auto& devicePort = port.ext.get<AudioPortExt::device>();
        if (xAttachedDeviceSet.count(port.name) != devicePort.device.type.connection.empty()) {
            LOG(ERROR) << __func__ << ": Review Audio Policy config: <attachedDevices> "
                       << "list is incorrect or devicePort \"" << port.name
                       << "\" type= " << devicePort.device.type.toString() << " is incorrect.";
            return unexpected(BAD_VALUE);
        }
    }
    return audioPortVec;
}

ConversionResult<AudioPort> convertMixPortToAidl(const ap_xsd::MixPorts::MixPort& xMixPort,
                                                 int32_t& nextPortId) {
    return AudioPort{
            .id = nextPortId++,
            .name = NON_EMPTY_STRING_OR_FATAL(xMixPort.getName()),
            .profiles = VALUE_OR_FATAL((convertCollectionToAidl<ap_xsd::Profile, AudioProfile>(
                    xMixPort.getProfile(), convertAudioProfileToAidl))),
            .flags = xMixPort.hasFlags()
                             ? VALUE_OR_FATAL(convertIoFlagsToAidl(xMixPort.getFlags(),
                                                                   xMixPort.getRole(), true))
                             : VALUE_OR_FATAL(convertIoFlagsToAidl({}, xMixPort.getRole(), true)),
            .gains = VALUE_OR_FATAL(
                    (convertWrappedCollectionToAidl<ap_xsd::Gains, ap_xsd::Gains::Gain, AudioGain>(
                            xMixPort.getGains(), &ap_xsd::Gains::getGain, &convertGainToAidl))),
            .ext = VALUE_OR_FATAL(createAudioPortExt(xMixPort)),
    };
}

ConversionResult<std::vector<AudioPort>> convertMixPortsInModuleToAidl(
        const ap_xsd::Modules::Module& xModuleConfig, int32_t& nextPortId) {
    std::vector<AudioPort> audioPortVec;
    std::vector<ap_xsd::MixPorts> xMixPortsVec = xModuleConfig.getMixPorts();
    if (xMixPortsVec.size() > 1) {
        LOG(ERROR) << __func__ << "Having multiple '<mixPorts>' elements is not allowed, found: "
                   << xMixPortsVec.size();
        return unexpected(BAD_VALUE);
    }
    if (!xMixPortsVec.empty()) {
        audioPortVec.reserve(xMixPortsVec[0].getMixPort().size());
        for (const ap_xsd::MixPorts& xMixPortsType : xMixPortsVec) {
            for (const ap_xsd::MixPorts::MixPort& xMixPort : xMixPortsType.getMixPort()) {
                audioPortVec.push_back(VALUE_OR_FATAL(convertMixPortToAidl(xMixPort, nextPortId)));
            }
        }
    }
    return audioPortVec;
}

ConversionResult<int32_t> getSinkPortId(const ap_xsd::Routes::Route& xRoute,
                                        const std::unordered_map<std::string, int32_t>& portMap) {
    auto portMapIter = portMap.find(xRoute.getSink());
    if (portMapIter == portMap.end()) {
        LOG(ERROR) << __func__ << " Review Audio Policy config: audio route"
                   << "has sink: " << xRoute.getSink()
                   << " which is neither a device port nor mix port.";
        return unexpected(BAD_VALUE);
    }
    return portMapIter->second;
}

ConversionResult<std::vector<int32_t>> getSourcePortIds(
        const ap_xsd::Routes::Route& xRoute,
        const std::unordered_map<std::string, int32_t>& portMap) {
    std::vector<int32_t> sourcePortIds;
    for (const std::string& rawSource : ::android::base::Split(xRoute.getSources(), ",")) {
        const std::string source = ::android::base::Trim(rawSource);
        auto portMapIter = portMap.find(source);
        if (portMapIter == portMap.end()) {
            LOG(ERROR) << __func__ << " Review Audio Policy config: audio route"
                       << "has source \"" << source
                       << "\" which is neither a device port nor mix port.";
            return unexpected(BAD_VALUE);
        }
        sourcePortIds.push_back(portMapIter->second);
    }
    return sourcePortIds;
}

ConversionResult<AudioRoute> convertRouteToAidl(const ap_xsd::Routes::Route& xRoute,
                                                const std::vector<AudioPort>& aidlAudioPorts) {
    std::unordered_map<std::string, int32_t> portMap;
    for (const AudioPort& port : aidlAudioPorts) {
        portMap.insert({port.name, port.id});
    }
    return AudioRoute{.sourcePortIds = VALUE_OR_FATAL(getSourcePortIds(xRoute, portMap)),
                      .sinkPortId = VALUE_OR_FATAL(getSinkPortId(xRoute, portMap)),
                      .isExclusive = (xRoute.getType() == ap_xsd::MixType::mux)};
}

ConversionResult<std::vector<AudioRoute>> convertRoutesInModuleToAidl(
        const ap_xsd::Modules::Module& xModuleConfig,
        const std::vector<AudioPort>& aidlAudioPorts) {
    std::vector<AudioRoute> audioRouteVec;
    std::vector<ap_xsd::Routes> xRoutesVec = xModuleConfig.getRoutes();
    if (!xRoutesVec.empty()) {
        /*
         * xRoutesVec likely only contains one element; that is, it's
         * likely that all ap_xsd::Routes::MixPort types that we need to convert
         * are inside of xRoutesVec[0].
         */
        audioRouteVec.reserve(xRoutesVec[0].getRoute().size());
        for (const ap_xsd::Routes& xRoutesType : xRoutesVec) {
            for (const ap_xsd::Routes::Route& xRoute : xRoutesType.getRoute()) {
                audioRouteVec.push_back(VALUE_OR_FATAL(convertRouteToAidl(xRoute, aidlAudioPorts)));
            }
        }
    }
    return audioRouteVec;
}

ConversionResult<std::unique_ptr<Module::Configuration>> convertModuleConfigToAidl(
        const ap_xsd::Modules::Module& xModuleConfig) {
    auto result = std::make_unique<Module::Configuration>();
    auto& aidlModuleConfig = *result;
    std::vector<AudioPort> devicePorts = VALUE_OR_FATAL(
            convertDevicePortsInModuleToAidl(xModuleConfig, aidlModuleConfig.nextPortId));

    // The XML config does not specify the default input device.
    // Assign the first attached input device as the default.
    for (auto& port : devicePorts) {
        if (port.flags.getTag() != AudioIoFlags::input) continue;
        auto& deviceExt = port.ext.get<AudioPortExt::device>();
        if (!deviceExt.device.type.connection.empty()) continue;
        deviceExt.flags |= 1 << AudioPortDeviceExt::FLAG_INDEX_DEFAULT_DEVICE;
        break;
    }

    std::vector<AudioPort> mixPorts = VALUE_OR_FATAL(
            convertMixPortsInModuleToAidl(xModuleConfig, aidlModuleConfig.nextPortId));
    aidlModuleConfig.ports.reserve(devicePorts.size() + mixPorts.size());
    aidlModuleConfig.ports.insert(aidlModuleConfig.ports.end(), devicePorts.begin(),
                                  devicePorts.end());
    aidlModuleConfig.ports.insert(aidlModuleConfig.ports.end(), mixPorts.begin(), mixPorts.end());

    aidlModuleConfig.routes =
            VALUE_OR_FATAL(convertRoutesInModuleToAidl(xModuleConfig, aidlModuleConfig.ports));
    return result;
}

ConversionResult<AudioMode> convertTelephonyModeToAidl(const std::string& xsdcModeCriterionType) {
    const auto it = std::find_if(kValidAudioModes.begin(), kValidAudioModes.end(),
                                 [&xsdcModeCriterionType](const auto& mode) {
                                     return toString(mode) == xsdcModeCriterionType;
                                 });
    if (it == kValidAudioModes.end()) {
        LOG(ERROR) << __func__ << " invalid mode " << xsdcModeCriterionType;
        return unexpected(BAD_VALUE);
    }
    return *it;
}

ConversionResult<AudioDeviceAddress> convertDeviceAddressToAidl(const std::string& xsdcAddress) {
    return AudioDeviceAddress::make<AudioDeviceAddress::Tag::id>(xsdcAddress);
}

ConversionResult<eng_xsd::CriterionTypeType> getCriterionTypeByName(
        const std::string& name,
        const std::vector<eng_xsd::CriterionTypesType>& xsdcCriterionTypesVec) {
    for (const auto& xsdCriterionTypes : xsdcCriterionTypesVec) {
        for (const auto& xsdcCriterionType : xsdCriterionTypes.getCriterion_type()) {
            if (xsdcCriterionType.getName() == name) {
                return xsdcCriterionType;
            }
        }
    }
    LOG(ERROR) << __func__ << " failed to find criterion type " << name;
    return unexpected(BAD_VALUE);
}

ConversionResult<std::vector<std::optional<AudioHalCapCriterionV2>>>
convertCapCriteriaCollectionToAidl(
        const std::vector<eng_xsd::CriteriaType>& xsdcCriteriaVec,
        const std::vector<eng_xsd::CriterionTypesType>& xsdcCriterionTypesVec) {
    std::vector<std::optional<AudioHalCapCriterionV2>> resultAidlCriterionVec;
    if (xsdcCriteriaVec.empty() || xsdcCriterionTypesVec.empty()) {
        LOG(ERROR) << __func__ << " empty criteria/criterionTypes";
        return unexpected(BAD_VALUE);
    }
    for (const auto& xsdCriteria : xsdcCriteriaVec) {
        for (const auto& xsdcCriterion : xsdCriteria.getCriterion()) {
            resultAidlCriterionVec.push_back(
                    std::optional<AudioHalCapCriterionV2>(VALUE_OR_FATAL(
                            convertCapCriterionV2ToAidl(xsdcCriterion, xsdcCriterionTypesVec))));
        }
    }
    return resultAidlCriterionVec;
}

ConversionResult<std::vector<AudioDeviceDescription>> convertDevicesToAidl(
        const eng_xsd::CriterionTypeType& xsdcDeviceCriterionType) {
    if (xsdcDeviceCriterionType.getValues().empty()) {
        LOG(ERROR) << __func__ << " no values provided";
        return unexpected(BAD_VALUE);
    }
    std::vector<AudioDeviceDescription> aidlDevices;
    for (eng_xsd::ValuesType xsdcValues : xsdcDeviceCriterionType.getValues()) {
        aidlDevices.reserve(xsdcValues.getValue().size());
        for (const eng_xsd::ValueType& xsdcValue : xsdcValues.getValue()) {
            if (!xsdcValue.hasAndroid_type()) {
                LOG(ERROR) << __func__ << " empty android type";
                return unexpected(BAD_VALUE);
            }
            uint32_t integerValue;
            if (!convertTo(xsdcValue.getAndroid_type(), integerValue)) {
                LOG(ERROR) << __func__ << " failed to convert android type "
                           << xsdcValue.getAndroid_type();
                return unexpected(BAD_VALUE);
            }
            aidlDevices.push_back(
                    VALUE_OR_RETURN(legacy2aidl_audio_devices_t_AudioDeviceDescription(
                            static_cast<audio_devices_t>(integerValue))));
        }
    }
    return aidlDevices;
}

ConversionResult<std::vector<AudioDeviceAddress>> convertDeviceAddressesToAidl(
        const eng_xsd::CriterionTypeType& xsdcDeviceAddressesCriterionType) {
    if (xsdcDeviceAddressesCriterionType.getValues().empty()) {
        LOG(ERROR) << __func__ << " no values provided";
        return unexpected(BAD_VALUE);
    }
    std::vector<AudioDeviceAddress> aidlDeviceAddresses;
    for (eng_xsd::ValuesType xsdcValues : xsdcDeviceAddressesCriterionType.getValues()) {
        aidlDeviceAddresses.reserve(xsdcValues.getValue().size());
        for (const eng_xsd::ValueType& xsdcValue : xsdcValues.getValue()) {
            aidlDeviceAddresses.push_back(
                    AudioDeviceAddress::make<AudioDeviceAddress::Tag::id>(xsdcValue.getLiteral()));
        }
    }
    return aidlDeviceAddresses;
}

ConversionResult<AudioMode> convertAudioModeToAidl(const std::string& xsdcAudioModeType) {
    const auto it = std::find_if(enum_range<AudioMode>().begin(), enum_range<AudioMode>().end(),
                                 [&](const auto v) { return toString(v) == xsdcAudioModeType; });
    if (it == enum_range<AudioMode>().end()) {
        LOG(ERROR) << __func__ << " invalid audio mode " << xsdcAudioModeType;
        return unexpected(BAD_VALUE);
    }
    return *it;
}

ConversionResult<std::vector<AudioMode>> convertTelephonyModesToAidl(
        const eng_xsd::CriterionTypeType& xsdcTelephonyModeCriterionType) {
    if (xsdcTelephonyModeCriterionType.getValues().empty()) {
        LOG(ERROR) << __func__ << " no values provided";
        return unexpected(BAD_VALUE);
    }
    std::vector<AudioMode> aidlAudioModes;
    for (eng_xsd::ValuesType xsdcValues : xsdcTelephonyModeCriterionType.getValues()) {
        aidlAudioModes.reserve(xsdcValues.getValue().size());
        for (const eng_xsd::ValueType& xsdcValue : xsdcValues.getValue()) {
            aidlAudioModes.push_back(
                    VALUE_OR_RETURN(convertAudioModeToAidl(xsdcValue.getLiteral())));
        }
    }
    return aidlAudioModes;
}

ConversionResult<std::vector<AudioPolicyForceUse>> convertForceUseConfigsToAidl(
        const std::string& criterionValue,
        const eng_xsd::CriterionTypeType& xsdcForcedConfigCriterionType) {
    if (xsdcForcedConfigCriterionType.getValues().empty()) {
        LOG(ERROR) << __func__ << " no values provided";
        return unexpected(BAD_VALUE);
    }
    std::vector<AudioPolicyForceUse> aidlForcedConfigs;
    for (eng_xsd::ValuesType xsdcValues : xsdcForcedConfigCriterionType.getValues()) {
        aidlForcedConfigs.reserve(xsdcValues.getValue().size());
        for (const eng_xsd::ValueType& xsdcValue : xsdcValues.getValue()) {
            aidlForcedConfigs.push_back(
                    VALUE_OR_RETURN(convertForceUseToAidl(criterionValue, xsdcValue.getLiteral())));
        }
    }
    return aidlForcedConfigs;
}

template <typename T>
ConversionResult<T> convertForceUseForcedConfigToAidl(
        const std::string& xsdcForcedConfigCriterionType) {
    const auto it = std::find_if(enum_range<T>().begin(), enum_range<T>().end(), [&](const auto v) {
        return toString(v) == xsdcForcedConfigCriterionType;
    });
    if (it == enum_range<T>().end()) {
        LOG(ERROR) << __func__ << " invalid forced config " << xsdcForcedConfigCriterionType;
        return unexpected(BAD_VALUE);
    }
    return *it;
}

ConversionResult<AudioPolicyForceUse> convertForceUseToAidl(const std::string& xsdcCriterionName,
                                                            const std::string& xsdcCriterionValue) {
    if (!fastcmp<strncmp>(xsdcCriterionName.c_str(), kXsdcForceConfigForCommunication,
                          strlen(kXsdcForceConfigForCommunication))) {
        const auto deviceCategory = VALUE_OR_RETURN(
                convertForceUseForcedConfigToAidl<AudioPolicyForceUse::CommunicationDeviceCategory>(
                        xsdcCriterionValue));
        return AudioPolicyForceUse::make<AudioPolicyForceUse::forCommunication>(deviceCategory);
    }
    if (!fasticmp<strncmp>(xsdcCriterionName.c_str(), kXsdcForceConfigForMedia,
            strlen(kXsdcForceConfigForMedia))) {
        const auto deviceCategory = VALUE_OR_RETURN(
                convertForceUseForcedConfigToAidl<AudioPolicyForceUse::MediaDeviceCategory>(
                        xsdcCriterionValue));
        return AudioPolicyForceUse::make<AudioPolicyForceUse::forMedia>(deviceCategory);
    }
    if (!fasticmp<strncmp>(xsdcCriterionName.c_str(), kXsdcForceConfigForRecord,
            strlen(kXsdcForceConfigForRecord))) {
        const auto deviceCategory = VALUE_OR_RETURN(
                convertForceUseForcedConfigToAidl<AudioPolicyForceUse::CommunicationDeviceCategory>(
                        xsdcCriterionValue));
        return AudioPolicyForceUse::make<AudioPolicyForceUse::forRecord>(deviceCategory);
    }
    if (!fasticmp<strncmp>(xsdcCriterionName.c_str(), kXsdcForceConfigForDock,
                           strlen(kXsdcForceConfigForDock))) {
        const auto dockType =
                VALUE_OR_RETURN(convertForceUseForcedConfigToAidl<AudioPolicyForceUse::DockType>(
                        xsdcCriterionValue));
        return AudioPolicyForceUse::make<AudioPolicyForceUse::dock>(dockType);
    }
    if (!fasticmp<strncmp>(xsdcCriterionName.c_str(), kXsdcForceConfigForSystem,
            strlen(kXsdcForceConfigForSystem))) {
        return AudioPolicyForceUse::make<AudioPolicyForceUse::systemSounds>(xsdcCriterionValue ==
                                                                            "SYSTEM_ENFORCED");
    }
    if (!fasticmp<strncmp>(xsdcCriterionName.c_str(), kXsdcForceConfigForHdmiSystemAudio,
            strlen(kXsdcForceConfigForHdmiSystemAudio))) {
        return AudioPolicyForceUse::make<AudioPolicyForceUse::hdmiSystemAudio>(
                xsdcCriterionValue == "HDMI_SYSTEM_AUDIO_ENFORCED");
    }
    if (!fasticmp<strncmp>(xsdcCriterionName.c_str(), kXsdcForceConfigForEncodedSurround,
            strlen(kXsdcForceConfigForEncodedSurround))) {
        const auto encodedSurround = VALUE_OR_RETURN(
                convertForceUseForcedConfigToAidl<AudioPolicyForceUse::EncodedSurroundConfig>(
                        xsdcCriterionValue));
        return AudioPolicyForceUse::make<AudioPolicyForceUse::encodedSurround>(encodedSurround);
    }
    if (!fasticmp<strncmp>(xsdcCriterionName.c_str(), kXsdcForceConfigForVibrateRinging,
            strlen(kXsdcForceConfigForVibrateRinging))) {
        const auto deviceCategory = VALUE_OR_RETURN(
                convertForceUseForcedConfigToAidl<AudioPolicyForceUse::CommunicationDeviceCategory>(
                        xsdcCriterionValue));
        return AudioPolicyForceUse::make<AudioPolicyForceUse::forVibrateRinging>(deviceCategory);
    }
    LOG(ERROR) << __func__ << " unrecognized force use " << xsdcCriterionName;
    return unexpected(BAD_VALUE);
}

ConversionResult<AudioHalCapCriterionV2> convertCapCriterionV2ToAidl(
        const eng_xsd::CriterionType& xsdcCriterion,
        const std::vector<eng_xsd::CriterionTypesType>& xsdcCriterionTypesVec) {
    eng_xsd::CriterionTypeType xsdcCriterionType =
            VALUE_OR_RETURN(getCriterionTypeByName(xsdcCriterion.getType(), xsdcCriterionTypesVec));
    std::string defaultLiteralValue =
            xsdcCriterion.has_default() ? xsdcCriterion.get_default() : "";
    using Tag = AudioHalCapCriterionV2::Tag;
    if (iequals(xsdcCriterion.getName(), toString(Tag::availableInputDevices))) {
        return AudioHalCapCriterionV2::make<Tag::availableInputDevices>(
                VALUE_OR_RETURN(convertDevicesToAidl(xsdcCriterionType)));
    }
    if (iequals(xsdcCriterion.getName(), toString(Tag::availableOutputDevices))) {
        return AudioHalCapCriterionV2::make<Tag::availableOutputDevices>(
                VALUE_OR_RETURN(convertDevicesToAidl(xsdcCriterionType)));
    }
    if (iequals(xsdcCriterion.getName(), toString(Tag::availableInputDevicesAddresses))) {
        return AudioHalCapCriterionV2::make<Tag::availableInputDevicesAddresses>(
                VALUE_OR_RETURN(convertDeviceAddressesToAidl(xsdcCriterionType)));
    }
    if (iequals(xsdcCriterion.getName(), toString(Tag::availableOutputDevicesAddresses))) {
        return AudioHalCapCriterionV2::make<Tag::availableOutputDevicesAddresses>(
                VALUE_OR_RETURN(convertDeviceAddressesToAidl(xsdcCriterionType)));
    }
    if (iequals(xsdcCriterion.getName(), toString(Tag::telephonyMode))) {
        return AudioHalCapCriterionV2::make<Tag::telephonyMode>(
                VALUE_OR_RETURN(convertTelephonyModesToAidl(xsdcCriterionType)));
    }
    if (!fastcmp<strncmp>(xsdcCriterion.getName().c_str(), kXsdcForceConfigForUse,
            strlen(kXsdcForceConfigForUse))) {
        return AudioHalCapCriterionV2::make<Tag::forceConfigForUse>(VALUE_OR_RETURN(
                convertForceUseConfigsToAidl(xsdcCriterion.getName(), xsdcCriterionType)));
    }
    LOG(ERROR) << __func__ << " unrecognized criterion " << xsdcCriterion.getName();
    return unexpected(BAD_VALUE);
}

ConversionResult<AudioHalCapCriterion> convertCapCriterionToAidl(
        const eng_xsd::CriterionType& xsdcCriterion) {
    AudioHalCapCriterion aidlCapCriterion;
    aidlCapCriterion.name = xsdcCriterion.getName();
    aidlCapCriterion.criterionTypeName = xsdcCriterion.getType();
    aidlCapCriterion.defaultLiteralValue =
            xsdcCriterion.has_default() ? xsdcCriterion.get_default() : "";
    return aidlCapCriterion;
}

ConversionResult<AudioHalVolumeCurve::CurvePoint> convertCurvePointToAidl(
        const std::string& xsdcCurvePoint) {
    AudioHalVolumeCurve::CurvePoint aidlCurvePoint{};
    if ((sscanf(xsdcCurvePoint.c_str(), "%" SCNd8 ",%d", &aidlCurvePoint.index,
                &aidlCurvePoint.attenuationMb) != 2) ||
        (aidlCurvePoint.index < AudioHalVolumeCurve::CurvePoint::MIN_INDEX) ||
        (aidlCurvePoint.index > AudioHalVolumeCurve::CurvePoint::MAX_INDEX)) {
        LOG(ERROR) << __func__ << " Review Audio Policy config: volume curve point:"
                   << "\"" << xsdcCurvePoint << "\" is invalid";
        return unexpected(BAD_VALUE);
    }
    return aidlCurvePoint;
}

/**
 * The hard coded id must be in sync with policy.h definition of legacy strategy ids.
 */
std::unordered_map<std::string, int> getLegacyProductStrategyMap() {
#define STRATEGY_ENTRY(name, id) {"STRATEGY_" #name, static_cast<int>(id)}

        return {STRATEGY_ENTRY(MEDIA, 5),
                STRATEGY_ENTRY(PHONE, 0),
                STRATEGY_ENTRY(SONIFICATION, 1),
                STRATEGY_ENTRY(SONIFICATION_RESPECTFUL, 4),
                STRATEGY_ENTRY(DTMF, 6),
                STRATEGY_ENTRY(ENFORCED_AUDIBLE, 2),
                STRATEGY_ENTRY(CALL_ASSISTANT, 7),
                STRATEGY_ENTRY(TRANSMITTED_THROUGH_SPEAKER,8),
                STRATEGY_ENTRY(ACCESSIBILITY, 3)};
#undef STRATEGY_ENTRY
}

}  // namespace aidl::android::hardware::audio::core::internal
