/*
 * 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 "file.h"

#include <binder/Functional.h>
#include <binder/RecordedTransaction.h>
#include <binder/unique_fd.h>

#include <inttypes.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <algorithm>

using namespace android::binder::impl;
using android::Parcel;
using android::binder::borrowed_fd;
using android::binder::ReadFully;
using android::binder::unique_fd;
using android::binder::WriteFully;
using android::binder::debug::RecordedTransaction;

#define PADDING8(s) ((8 - (s) % 8) % 8)

static_assert(PADDING8(0) == 0);
static_assert(PADDING8(1) == 7);
static_assert(PADDING8(7) == 1);
static_assert(PADDING8(8) == 0);

// Transactions are sequentially recorded to a file descriptor.
//
// An individual RecordedTransaction is written with the following format:
//
// WARNING: Though the following format is designed to be stable and
// extensible, it is under active development and should be considered
// unstable until this warning is removed.
//
// A RecordedTransaction is written to a file as a sequence of Chunks.
//
// A Chunk consists of a ChunkDescriptor, Data, Padding, and a Checksum.
//
// The ChunkDescriptor identifies the type of Data in the chunk, and the size
// of the Data.
//
// The Data may be any uint32 number of bytes in length in [0-0xfffffff0].
//
// Padding is between [0-7] zero-bytes after the Data such that the Chunk ends
// on an 8-byte boundary. The ChunkDescriptor's dataSize does not include the
// size of Padding.
//
// The checksum is a 64-bit wide XOR of all previous data from the start of the
// ChunkDescriptor to the end of Padding.
//
// ┌───────────────────────────┐
// │Chunk                      │
// │┌────────────────────────┐ │
// ││ChunkDescriptor         │ │
// ││┌───────────┬──────────┐│ │
// │││chunkType  │dataSize  ├┼─┼─┐
// │││uint32_t   │uint32_t  ││ │ │
// ││└───────────┴──────────┘│ │ │
// │└────────────────────────┘ │ │
// │┌─────────────────────────┐│ │
// ││Data                     ││ │
// ││bytes * dataSize         │◀─┘
// ││   ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┤│
// ││           Padding       ││
// │└───┴─────────────────────┘│
// │┌─────────────────────────┐│
// ││checksum                 ││
// ││uint64_t                 ││
// │└─────────────────────────┘│
// └───────────────────────────┘
//
// A RecordedTransaction is written as a Header Chunk with fields about the
// transaction, a Data Parcel chunk, a Reply Parcel Chunk, and an End Chunk.
// ┌──────────────────────┐
// │     Header Chunk     │
// ├──────────────────────┤
// │  Sent Parcel Chunk   │
// ├──────────────────────┤
// │  Reply Parcel Chunk  │
// ├──────────────────────┤
// ║      End Chunk       ║
// ╚══════════════════════╝
//
// On reading a RecordedTransaction, an unrecognized chunk is checksummed
// then skipped according to size information in the ChunkDescriptor. Chunks
// are read and either assimilated or skipped until an End Chunk is
// encountered. This has three notable implications:
//
// 1. Older and newer implementations should be able to read one another's
//    Transactions, though there will be loss of information.
// 2. With the exception of the End Chunk, Chunks can appear in any order
//    and even repeat, though this is not recommended.
// 3. If any Chunk is repeated, old values will be overwritten by versions
//    encountered later in the file.
//
// No effort is made to ensure the expected chunks are present. A single
// End Chunk may therefore produce an empty, meaningless RecordedTransaction.

RecordedTransaction::RecordedTransaction(RecordedTransaction&& t) noexcept {
    mData = t.mData;
    mSentDataOnly.setData(t.getDataParcel().data(), t.getDataParcel().dataSize());
    mReplyDataOnly.setData(t.getReplyParcel().data(), t.getReplyParcel().dataSize());
}

std::optional<RecordedTransaction> RecordedTransaction::fromDetails(
        const String16& interfaceName, uint32_t code, uint32_t flags, timespec timestamp,
        const Parcel& dataParcel, const Parcel& replyParcel, status_t err) {
    RecordedTransaction t;
    t.mData.mHeader = {code,
                       flags,
                       static_cast<int32_t>(err),
                       dataParcel.isForRpc() ? static_cast<uint32_t>(1) : static_cast<uint32_t>(0),
                       static_cast<int64_t>(timestamp.tv_sec),
                       static_cast<int32_t>(timestamp.tv_nsec),
                       0};

    t.mData.mInterfaceName = std::string(String8(interfaceName).c_str());
    if (interfaceName.size() != t.mData.mInterfaceName.size()) {
        ALOGE("Interface Name is not valid. Contains characters that aren't single byte utf-8.");
        return std::nullopt;
    }

    if (const auto* kernelFields = dataParcel.maybeKernelFields()) {
        for (size_t i = 0; i < kernelFields->mObjectsSize; i++) {
            uint64_t offset = kernelFields->mObjects[i];
            t.mData.mSentObjectData.push_back(offset);
        }
    }

    if (t.mSentDataOnly.setData(dataParcel.data(), dataParcel.dataBufferSize()) !=
        android::NO_ERROR) {
        ALOGE("Failed to set sent parcel data.");
        return std::nullopt;
    }

    if (t.mReplyDataOnly.setData(replyParcel.data(), replyParcel.dataBufferSize()) !=
        android::NO_ERROR) {
        ALOGE("Failed to set reply parcel data.");
        return std::nullopt;
    }

    return std::optional<RecordedTransaction>(std::move(t));
}

enum {
    HEADER_CHUNK = 1,
    DATA_PARCEL_CHUNK = 2,
    REPLY_PARCEL_CHUNK = 3,
    INTERFACE_NAME_CHUNK = 4,
    DATA_PARCEL_OBJECT_CHUNK = 5,
    END_CHUNK = 0x00ffffff,
};

struct ChunkDescriptor {
    uint32_t chunkType = 0;
    uint32_t dataSize = 0;
};
static_assert(sizeof(ChunkDescriptor) % 8 == 0);

constexpr uint32_t kMaxChunkDataSize = 0xfffffff0;
typedef uint64_t transaction_checksum_t;

std::optional<RecordedTransaction> RecordedTransaction::fromFile(const unique_fd& fd) {
    RecordedTransaction t;
    ChunkDescriptor chunk;
    const long pageSize = sysconf(_SC_PAGE_SIZE);
    struct stat fileStat;
    if (fstat(fd.get(), &fileStat) != 0) {
        ALOGE("Unable to get file information");
        return std::nullopt;
    }

    off_t fdCurrentPosition = lseek(fd.get(), 0, SEEK_CUR);
    if (fdCurrentPosition == -1) {
        ALOGE("Invalid offset in file descriptor.");
        return std::nullopt;
    }
    do {
        if (fileStat.st_size < (fdCurrentPosition + (off_t)sizeof(ChunkDescriptor))) {
            ALOGE("Not enough file remains to contain expected chunk descriptor");
            return std::nullopt;
        }

        if (!ReadFully(fd, &chunk, sizeof(ChunkDescriptor))) {
            ALOGE("Failed to read ChunkDescriptor from fd %d. %s", fd.get(), strerror(errno));
            return std::nullopt;
        }
        transaction_checksum_t checksum = *reinterpret_cast<transaction_checksum_t*>(&chunk);

        fdCurrentPosition = lseek(fd.get(), 0, SEEK_CUR);
        if (fdCurrentPosition == -1) {
            ALOGE("Invalid offset in file descriptor.");
            return std::nullopt;
        }
        off_t mmapPageAlignedStart = (fdCurrentPosition / pageSize) * pageSize;
        off_t mmapPayloadStartOffset = fdCurrentPosition - mmapPageAlignedStart;

        if (chunk.dataSize > kMaxChunkDataSize) {
            ALOGE("Chunk data exceeds maximum size.");
            return std::nullopt;
        }

        size_t chunkPayloadSize =
                chunk.dataSize + PADDING8(chunk.dataSize) + sizeof(transaction_checksum_t);

        if (chunkPayloadSize > (size_t)(fileStat.st_size - fdCurrentPosition)) {
            ALOGE("Chunk payload exceeds remaining file size.");
            return std::nullopt;
        }

        if (PADDING8(chunkPayloadSize) != 0) {
            ALOGE("Invalid chunk size, not aligned %zu", chunkPayloadSize);
            return std::nullopt;
        }

        size_t memoryMappedSize = chunkPayloadSize + mmapPayloadStartOffset;
        void* mappedMemory =
                mmap(NULL, memoryMappedSize, PROT_READ, MAP_SHARED, fd.get(), mmapPageAlignedStart);
        auto mmap_guard = make_scope_guard(
                [mappedMemory, memoryMappedSize] { munmap(mappedMemory, memoryMappedSize); });

        transaction_checksum_t* payloadMap =
                reinterpret_cast<transaction_checksum_t*>(mappedMemory);
        payloadMap += mmapPayloadStartOffset /
                sizeof(transaction_checksum_t); // Skip chunk descriptor and required mmap
                                                // page-alignment
        if (payloadMap == MAP_FAILED) {
            ALOGE("Memory mapping failed for fd %d: %d %s", fd.get(), errno, strerror(errno));
            return std::nullopt;
        }
        for (size_t checksumIndex = 0;
             checksumIndex < chunkPayloadSize / sizeof(transaction_checksum_t); checksumIndex++) {
            checksum ^= payloadMap[checksumIndex];
        }
        if (checksum != 0) {
            ALOGE("Checksum failed.");
            return std::nullopt;
        }

        fdCurrentPosition = lseek(fd.get(), chunkPayloadSize, SEEK_CUR);
        if (fdCurrentPosition == -1) {
            ALOGE("Invalid offset in file descriptor.");
            return std::nullopt;
        }

        switch (chunk.chunkType) {
            case HEADER_CHUNK: {
                if (chunk.dataSize != static_cast<uint32_t>(sizeof(TransactionHeader))) {
                    ALOGE("Header Chunk indicated size %" PRIu32 "; Expected %zu.", chunk.dataSize,
                          sizeof(TransactionHeader));
                    return std::nullopt;
                }
                t.mData.mHeader = *reinterpret_cast<TransactionHeader*>(payloadMap);
                break;
            }
            case INTERFACE_NAME_CHUNK: {
                t.mData.mInterfaceName =
                        std::string(reinterpret_cast<char*>(payloadMap), chunk.dataSize);
                break;
            }
            case DATA_PARCEL_CHUNK: {
                if (t.mSentDataOnly.setData(reinterpret_cast<const unsigned char*>(payloadMap),
                                            chunk.dataSize) != android::NO_ERROR) {
                    ALOGE("Failed to set sent parcel data.");
                    return std::nullopt;
                }
                break;
            }
            case REPLY_PARCEL_CHUNK: {
                if (t.mReplyDataOnly.setData(reinterpret_cast<const unsigned char*>(payloadMap),
                                             chunk.dataSize) != android::NO_ERROR) {
                    ALOGE("Failed to set reply parcel data.");
                    return std::nullopt;
                }
                break;
            }
            case DATA_PARCEL_OBJECT_CHUNK: {
                const uint64_t* objects = reinterpret_cast<const uint64_t*>(payloadMap);
                size_t metaDataSize = (chunk.dataSize / sizeof(uint64_t));
                ALOGI("Total objects found in saved parcel %zu", metaDataSize);
                for (size_t index = 0; index < metaDataSize; ++index) {
                    t.mData.mSentObjectData.push_back(objects[index]);
                }
                break;
            }
            case END_CHUNK:
                break;
            default:
                ALOGI("Unrecognized chunk.");
                break;
        }
    } while (chunk.chunkType != END_CHUNK);

    return std::optional<RecordedTransaction>(std::move(t));
}

android::status_t RecordedTransaction::writeChunk(borrowed_fd fd, uint32_t chunkType,
                                                  size_t byteCount, const uint8_t* data) const {
    if (byteCount > kMaxChunkDataSize) {
        ALOGE("Chunk data exceeds maximum size");
        return BAD_VALUE;
    }
    ChunkDescriptor descriptor = {.chunkType = chunkType,
                                  .dataSize = static_cast<uint32_t>(byteCount)};
    // Prepare Chunk content as byte *
    const std::byte* descriptorBytes = reinterpret_cast<const std::byte*>(&descriptor);
    const std::byte* dataBytes = reinterpret_cast<const std::byte*>(data);

    // Add Chunk to intermediate buffer, except checksum
    std::vector<std::byte> buffer;
    buffer.insert(buffer.end(), descriptorBytes, descriptorBytes + sizeof(ChunkDescriptor));
    buffer.insert(buffer.end(), dataBytes, dataBytes + byteCount);
    std::byte zero{0};
    buffer.insert(buffer.end(), PADDING8(byteCount), zero);

    // Calculate checksum from buffer
    transaction_checksum_t* checksumData = reinterpret_cast<transaction_checksum_t*>(buffer.data());
    transaction_checksum_t checksumValue = 0;
    for (size_t idx = 0; idx < (buffer.size() / sizeof(transaction_checksum_t)); idx++) {
        checksumValue ^= checksumData[idx];
    }

    // Write checksum to buffer
    std::byte* checksumBytes = reinterpret_cast<std::byte*>(&checksumValue);
    buffer.insert(buffer.end(), checksumBytes, checksumBytes + sizeof(transaction_checksum_t));

    // Write buffer to file
    if (!WriteFully(fd, buffer.data(), buffer.size())) {
        ALOGE("Failed to write chunk fd %d", fd.get());
        return UNKNOWN_ERROR;
    }
    return NO_ERROR;
}

android::status_t RecordedTransaction::dumpToFile(const unique_fd& fd) const {
    if (NO_ERROR !=
        writeChunk(fd, HEADER_CHUNK, sizeof(TransactionHeader),
                   reinterpret_cast<const uint8_t*>(&(mData.mHeader)))) {
        ALOGE("Failed to write transactionHeader to fd %d", fd.get());
        return UNKNOWN_ERROR;
    }
    if (NO_ERROR !=
        writeChunk(fd, INTERFACE_NAME_CHUNK, mData.mInterfaceName.size() * sizeof(uint8_t),
                   reinterpret_cast<const uint8_t*>(mData.mInterfaceName.c_str()))) {
        ALOGI("Failed to write Interface Name Chunk to fd %d", fd.get());
        return UNKNOWN_ERROR;
    }

    if (NO_ERROR !=
        writeChunk(fd, DATA_PARCEL_CHUNK, mSentDataOnly.dataBufferSize(), mSentDataOnly.data())) {
        ALOGE("Failed to write sent Parcel to fd %d", fd.get());
        return UNKNOWN_ERROR;
    }

    if (NO_ERROR !=
        writeChunk(fd, REPLY_PARCEL_CHUNK, mReplyDataOnly.dataBufferSize(),
                   mReplyDataOnly.data())) {
        ALOGE("Failed to write reply Parcel to fd %d", fd.get());
        return UNKNOWN_ERROR;
    }

    if (NO_ERROR !=
        writeChunk(fd, DATA_PARCEL_OBJECT_CHUNK, mData.mSentObjectData.size() * sizeof(uint64_t),
                   reinterpret_cast<const uint8_t*>(mData.mSentObjectData.data()))) {
        ALOGE("Failed to write sent parcel object metadata to fd %d", fd.get());
        return UNKNOWN_ERROR;
    }

    if (NO_ERROR != writeChunk(fd, END_CHUNK, 0, NULL)) {
        ALOGE("Failed to write end chunk to fd %d", fd.get());
        return UNKNOWN_ERROR;
    }
    return NO_ERROR;
}

const std::string& RecordedTransaction::getInterfaceName() const {
    return mData.mInterfaceName;
}

uint32_t RecordedTransaction::getCode() const {
    return mData.mHeader.code;
}

uint32_t RecordedTransaction::getFlags() const {
    return mData.mHeader.flags;
}

int32_t RecordedTransaction::getReturnedStatus() const {
    return mData.mHeader.statusReturned;
}

timespec RecordedTransaction::getTimestamp() const {
    time_t sec = mData.mHeader.timestampSeconds;
    int32_t nsec = mData.mHeader.timestampNanoseconds;
    return (timespec){.tv_sec = sec, .tv_nsec = nsec};
}

uint32_t RecordedTransaction::getVersion() const {
    return mData.mHeader.version;
}

const std::vector<uint64_t>& RecordedTransaction::getObjectOffsets() const {
    return mData.mSentObjectData;
}

const Parcel& RecordedTransaction::getDataParcel() const {
    return mSentDataOnly;
}

const Parcel& RecordedTransaction::getReplyParcel() const {
    return mReplyDataOnly;
}
