/*
 * Copyright (C) 2022 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 <algorithm>
#include <cstdint>
#include <cstring>
#include <sys/mman.h>
#define LOG_TAG "EffectBufferHalAidl"
//#define LOG_NDEBUG 0

#include <cutils/ashmem.h>
#include <utils/Log.h>

#include "EffectBufferHalAidl.h"

using ndk::ScopedFileDescriptor;

namespace android {
namespace effect {

// static
status_t EffectBufferHalAidl::allocate(size_t size, sp<EffectBufferHalInterface>* buffer) {
    return mirror(nullptr, size, buffer);
}

status_t EffectBufferHalAidl::mirror(void* external, size_t size,
                                     sp<EffectBufferHalInterface>* buffer) {
    sp<EffectBufferHalAidl> tempBuffer = new EffectBufferHalAidl(size);
    status_t status = tempBuffer.get()->init();
    if (status != OK) {
        ALOGE("%s init failed %d", __func__, status);
        return status;
    }

    tempBuffer->setExternalData(external);
    *buffer = tempBuffer;
    return OK;
}

EffectBufferHalAidl::EffectBufferHalAidl(size_t size)
    : mBufferSize(size),
      mFrameCountChanged(false),
      mExternalData(nullptr),
      mAudioBuffer{0, {nullptr}} {
}

EffectBufferHalAidl::~EffectBufferHalAidl() {
}

status_t EffectBufferHalAidl::init() {
    int fd = ashmem_create_region("audioEffectAidl", mBufferSize);
    if (fd < 0) {
        ALOGE("%s create ashmem failed %d", __func__, fd);
        return fd;
    }

    ScopedFileDescriptor tempFd(fd);
    mAudioBuffer.raw = mmap(nullptr /* address */, mBufferSize /* length */, PROT_READ | PROT_WRITE,
                            MAP_SHARED, fd, 0 /* offset */);
    if (mAudioBuffer.raw == MAP_FAILED) {
        ALOGE("mmap failed for fd %d", fd);
        mAudioBuffer.raw = nullptr;
        return INVALID_OPERATION;
    }

    mMemory = {std::move(tempFd), static_cast<int64_t>(mBufferSize)};
    return OK;
}

audio_buffer_t* EffectBufferHalAidl::audioBuffer() {
    return &mAudioBuffer;
}

void* EffectBufferHalAidl::externalData() const {
    return mExternalData;
}

void EffectBufferHalAidl::setFrameCount(size_t frameCount) {
    mAudioBuffer.frameCount = frameCount;
    mFrameCountChanged = true;
}

bool EffectBufferHalAidl::checkFrameCountChange() {
    bool result = mFrameCountChanged;
    mFrameCountChanged = false;
    return result;
}

void EffectBufferHalAidl::setExternalData(void* external) {
    mExternalData = external;
}

void EffectBufferHalAidl::update() {
    update(mBufferSize);
}

void EffectBufferHalAidl::commit() {
    commit(mBufferSize);
}

void EffectBufferHalAidl::copy(void* dst, const void* src, size_t n) const {
    if (!dst || !src) {
        return;
    }
    std::memcpy(dst, src, std::min(n, mBufferSize));
}

void EffectBufferHalAidl::update(size_t n) {
    copy(mAudioBuffer.raw, mExternalData, n);
}

void EffectBufferHalAidl::commit(size_t n) {
    copy(mExternalData, mAudioBuffer.raw, n);
}

} // namespace effect
} // namespace android
