/*
 * Copyright (c) 2026 Huawei Device Co., Ltd.
 * 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 "AudioVividWrapper.h"
#include <multimedia/native_audio_channel_layout.h>
#include <multimedia/player_framework/native_avcodec_base.h>
#include <vector>

AudioVividWrapper::AudioVividWrapper() : builder_(nullptr)
{}

AudioVividWrapper::~AudioVividWrapper()
{
    Destroy();
}

bool AudioVividWrapper::Initialize()
{
    OH_AVFormat *format = OH_AVFormat_Create();
    if (!format) {
        return false;
    }
    // 演示的PCM为2声道声床+2个对象,因此信号格式为MIX
    OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUDIO_VIVID_SIGNAL_FORMAT, OH_AUDIO_VIVID_SIGNAL_FORMAT_MIX);
    // 设置声床的声道布局,这里声床为立体声
    OH_AVFormat_SetLongValue(format, OH_MD_KEY_AUDIO_SOUNDBED_LAYOUT, OH_AudioChannelLayout::CH_LAYOUT_STEREO);
    // 设置对象个数2个
    OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUDIO_OBJECT_NUMBER, 2);
    OH_AVErrCode result = OH_AudioVividMetaBuilder_Create(&builder_, format);
    if (result != AV_ERR_OK) {
        AVCODEC_SAMPLE_LOGI("vivid create error:%{public}d", result);
        return false;
    }
    AVCODEC_SAMPLE_LOGI("vivid create success");
    OH_AVFormat_Destroy(format);
    return builder_ != nullptr;
}

void AudioVividWrapper::Destroy()
{
    if (builder_) {
        OH_AudioVividMetaBuilder_Destroy(builder_);
        builder_ = nullptr;
    }
}

bool AudioVividWrapper::UpdateObjectPosition(int objectIndex, float x, float y, float z)
{
    if (!builder_) {
        return false;
    }
    OH_AudioObjectPosition pos;
    pos.isCartesian = true;
    pos.pos.cartesian.x = x;
    pos.pos.cartesian.y = y;
    pos.pos.cartesian.z = z;
    OH_AVErrCode result = OH_AudioVividMetaBuilder_UpdateObjectPos(builder_, objectIndex, pos);
    if (result != AV_ERR_OK) {
        AVCODEC_SAMPLE_LOGI("OH_AudioVividMetaBuilder_UpdateObjectPos error:%{public}d", result);
        return false;
    }
    AVCODEC_SAMPLE_LOGI("OH_AudioVividMetaBuilder_UpdateObjectPos index:%{public}f", objectIndex);
    return result == OH_AVErrCode::AV_ERR_OK;
}

bool AudioVividWrapper::UpdateObjectGain(int objectIndex, float gain)
{
    if (!builder_) {
        AVCODEC_SAMPLE_LOGI("UpdateObjectGain: builder is null");
        return false;
    }
    AVCODEC_SAMPLE_LOGI("UpdateObjectGain: objectIndex=%d, gain=%f", objectIndex, gain);
    OH_AVErrCode result = OH_AudioVividMetaBuilder_UpdateObjectGain(builder_, objectIndex, gain);
    if (result != AV_ERR_OK) {
        AVCODEC_SAMPLE_LOGI("OH_AudioVividMetaBuilder_UpdateObjectGain error:%{public}d", result);
        return false;
    }
    AVCODEC_SAMPLE_LOGI("OH_AudioVividMetaBuilder_UpdateObjectGain success, gain=%{public}f", gain);
    return result == OH_AVErrCode::AV_ERR_OK;
}

std::vector<uint8_t> AudioVividWrapper::GetMetadata(bool withStaticMeta)
{
    std::vector<uint8_t> result;
    if (!builder_) {
        return result;
    }
    int32_t len = 0;
    OH_AVErrCode ret = OH_AudioVividMetaBuilder_GetMetaLen(builder_, withStaticMeta, &len);
    if (ret != OH_AVErrCode::AV_ERR_OK || len <= 0) {
        return result;
    }
    result.resize(len);
    ret = OH_AudioVividMetaBuilder_GetMeta(builder_, withStaticMeta, result.data(), len);
    if (ret != OH_AVErrCode::AV_ERR_OK) {
        result.clear();
        return result;
    }
    return result;
}