// Copyright 2018 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 "android/base/AndroidSubAllocator.h"

#include "android/base/address_space.h"
#include "android/base/files/Stream.h"

#include <iomanip>
#include <sstream>
#include <string>

#include <log/log.h>

namespace android {
namespace base {
namespace guest {

class SubAllocator::Impl {
public:
    Impl(
        void* _buffer,
        uint64_t _totalSize,
        uint64_t _pageSize) :
        buffer(_buffer),
        totalSize(_totalSize),
        pageSize(_pageSize),
        startAddr((uintptr_t)buffer),
        endAddr(startAddr + totalSize) {

        address_space_allocator_init(
            &addr_alloc,
            totalSize,
            32);
    }

    ~Impl() {
        address_space_allocator_destroy_nocleanup(&addr_alloc);
    }

    void clear() {
        address_space_allocator_destroy_nocleanup(&addr_alloc);
        address_space_allocator_init(
            &addr_alloc,
            totalSize,
            32);
    }

    bool save(Stream* stream) {
        address_space_allocator_iter_func_t allocatorSaver =
            [](void* context, struct address_space_allocator* allocator) {
                Stream* stream = reinterpret_cast<Stream*>(context);
                stream->putBe32(allocator->size);
                stream->putBe32(allocator->capacity);
                stream->putBe64(allocator->total_bytes);
            };
        address_block_iter_func_t allocatorBlockSaver =
            [](void* context, struct address_block* block) {
                Stream* stream = reinterpret_cast<Stream*>(context);
                stream->putBe64(block->offset);
                stream->putBe64(block->size_available);
            };
        address_space_allocator_run(
            &addr_alloc,
            (void*)stream,
            allocatorSaver,
            allocatorBlockSaver);

        stream->putBe64(pageSize);
        stream->putBe64(totalSize);
        stream->putBe32(allocCount);

        return true;
    }

    bool load(Stream* stream) {
        clear();
        address_space_allocator_iter_func_t allocatorLoader =
            [](void* context, struct address_space_allocator* allocator) {
                Stream* stream = reinterpret_cast<Stream*>(context);
                allocator->size = stream->getBe32();
                allocator->capacity = stream->getBe32();
                allocator->total_bytes = stream->getBe64();
            };
        address_block_iter_func_t allocatorBlockLoader =
            [](void* context, struct address_block* block) {
                Stream* stream = reinterpret_cast<Stream*>(context);
                block->offset = stream->getBe64();
                block->size_available = stream->getBe64();
            };
        address_space_allocator_run(
            &addr_alloc,
            (void*)stream,
            allocatorLoader,
            allocatorBlockLoader);

        pageSize = stream->getBe64();
        totalSize = stream->getBe64();
        allocCount = stream->getBe32();

        return true;
    }

    bool postLoad(void* postLoadBuffer) {
        buffer = postLoadBuffer;
        startAddr =
            (uint64_t)(uintptr_t)postLoadBuffer;
        return true;
    }

    void rangeCheck(const char* task, void* ptr) {
        uint64_t addr = (uintptr_t)ptr;
        if (addr < startAddr ||
            addr > endAddr) {
            std::stringstream ss;
            ss << "SubAllocator " << task << ": ";
            ss << "Out of range: " << std::hex << addr << " ";
            ss << "Range: " <<
                std::hex << startAddr << " " <<
                std::hex << endAddr;
            std::string msg = ss.str();
            ALOGE("Fatal: %s\n", msg.c_str());
        }
    }

    uint64_t getOffset(void* checkedPtr) {
        uint64_t addr = (uintptr_t)checkedPtr;
        return addr - startAddr;
    }

    bool free(void* ptr) {
        if (!ptr) return false;

        rangeCheck("free", ptr);
        if (EINVAL == address_space_allocator_deallocate(
            &addr_alloc, getOffset(ptr))) {
            return false;
        }

        --allocCount;
        return true;
    }

    void freeAll() {
        address_space_allocator_reset(&addr_alloc);
        allocCount = 0;
    }

    void* alloc(size_t wantedSize) {
        if (wantedSize == 0) return nullptr;

        uint64_t wantedSize64 =
            (uint64_t)wantedSize;

        size_t toPageSize =
            pageSize *
            ((wantedSize + pageSize - 1) / pageSize);

        uint64_t offset =
            address_space_allocator_allocate(
                &addr_alloc, toPageSize);

        if (offset == ANDROID_EMU_ADDRESS_SPACE_BAD_OFFSET) {
            return nullptr;
        }

        ++allocCount;
        return (void*)(uintptr_t)(startAddr + offset);
    }

    bool empty() const {
        return allocCount == 0;
    }

    void* buffer;
    uint64_t totalSize;
    uint64_t pageSize;
    uint64_t startAddr;
    uint64_t endAddr;
    struct address_space_allocator addr_alloc;
    uint32_t allocCount = 0;
};

SubAllocator::SubAllocator(
    void* buffer,
    uint64_t totalSize,
    uint64_t pageSize) :
    mImpl(
        new SubAllocator::Impl(buffer, totalSize, pageSize)) { }

SubAllocator::~SubAllocator() {
    delete mImpl;
}

// Snapshotting
bool SubAllocator::save(Stream* stream) {
    return mImpl->save(stream);
}

bool SubAllocator::load(Stream* stream) {
    return mImpl->load(stream);
}

bool SubAllocator::postLoad(void* postLoadBuffer) {
    return mImpl->postLoad(postLoadBuffer);
}

void* SubAllocator::alloc(size_t wantedSize) {
    return mImpl->alloc(wantedSize);
}

bool SubAllocator::free(void* ptr) {
    return mImpl->free(ptr);
}

void SubAllocator::freeAll() {
    mImpl->freeAll();
}

uint64_t SubAllocator::getOffset(void* ptr) {
    return mImpl->getOffset(ptr);
}

bool SubAllocator::empty() const {
    return mImpl->empty();
}

} // namespace guest
} // namespace base
} // namespace android
