/*
 * Copyright (C) 2017 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 "SharedMemoryProxy"
//#define LOG_NDEBUG 0
#include <log/log.h>

#include <errno.h>
#include <string.h>
#include <unistd.h>

#include <aaudio/AAudio.h>
#include "SharedMemoryProxy.h"

using namespace aaudio;

SharedMemoryProxy::~SharedMemoryProxy()
{
    if (mOriginalSharedMemory != nullptr) {
        munmap(mOriginalSharedMemory, mSharedMemorySizeInBytes);
        mOriginalSharedMemory = nullptr;
    }
    if (mProxySharedMemory != nullptr) {
        munmap(mProxySharedMemory, mSharedMemorySizeInBytes);
        close(mProxyFileDescriptor);
        mProxySharedMemory = nullptr;
    }
}

aaudio_result_t SharedMemoryProxy::open(int originalFD, int32_t capacityInBytes) {
    mOriginalFileDescriptor = originalFD;
    mSharedMemorySizeInBytes = capacityInBytes;

    mProxyFileDescriptor = ashmem_create_region("AAudioProxyDataBuffer", mSharedMemorySizeInBytes);
    if (mProxyFileDescriptor < 0) {
        ALOGE("open() ashmem_create_region() failed %d", errno);
        return AAUDIO_ERROR_INTERNAL;
    }
    int err = ashmem_set_prot_region(mProxyFileDescriptor, PROT_READ|PROT_WRITE);
    if (err < 0) {
        ALOGE("open() ashmem_set_prot_region() failed %d", errno);
        close(mProxyFileDescriptor);
        mProxyFileDescriptor = -1;
        return AAUDIO_ERROR_INTERNAL; // TODO convert errno to a better AAUDIO_ERROR;
    }

    // Get original memory address.
    mOriginalSharedMemory = (uint8_t *) mmap(nullptr, mSharedMemorySizeInBytes,
                         PROT_READ|PROT_WRITE,
                         MAP_SHARED,
                         mOriginalFileDescriptor, 0);
    if (mOriginalSharedMemory == MAP_FAILED) {
        ALOGE("open() original mmap(%d) failed %d (%s)",
                mOriginalFileDescriptor, errno, strerror(errno));
        return AAUDIO_ERROR_INTERNAL; // TODO convert errno to a better AAUDIO_ERROR;
    }

    // Map the fd to the same memory addresses.
    mProxySharedMemory = (uint8_t *) mmap(mOriginalSharedMemory, mSharedMemorySizeInBytes,
                         PROT_READ|PROT_WRITE,
                         MAP_SHARED,
                         mProxyFileDescriptor, 0);
    if (mProxySharedMemory != mOriginalSharedMemory) {
        ALOGE("open() proxy mmap(%d) failed %d", mProxyFileDescriptor, errno);
        munmap(mOriginalSharedMemory, mSharedMemorySizeInBytes);
        mOriginalSharedMemory = nullptr;
        close(mProxyFileDescriptor);
        mProxyFileDescriptor = -1;
        return AAUDIO_ERROR_INTERNAL; // TODO convert errno to a better AAUDIO_ERROR;
    }

    return AAUDIO_OK;
}
