// Copyright (C) 2023 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 <snapuserd/dm_user_block_server.h>

#include <android-base/file.h>
#include <android-base/logging.h>
#include <snapuserd/snapuserd_kernel.h>
#include "snapuserd_logging.h"

namespace android {
namespace snapshot {

using android::base::unique_fd;

DmUserBlockServer::DmUserBlockServer(const std::string& misc_name, unique_fd&& ctrl_fd,
                                     Delegate* delegate, size_t buffer_size)
    : misc_name_(misc_name), ctrl_fd_(std::move(ctrl_fd)), delegate_(delegate) {
    buffer_.Initialize(buffer_size);
}

bool DmUserBlockServer::ProcessRequests() {
    struct dm_user_header* header = buffer_.GetHeaderPtr();
    if (!android::base::ReadFully(ctrl_fd_, header, sizeof(*header))) {
        if (errno != ENOTBLK) {
            SNAP_PLOG(ERROR) << "Control-read failed";
        }

        SNAP_PLOG(DEBUG) << "ReadDmUserHeader failed....";
        return false;
    }

    SNAP_LOG(DEBUG) << "Daemon: msg->seq: " << std::dec << header->seq;
    SNAP_LOG(DEBUG) << "Daemon: msg->len: " << std::dec << header->len;
    SNAP_LOG(DEBUG) << "Daemon: msg->sector: " << std::dec << header->sector;
    SNAP_LOG(DEBUG) << "Daemon: msg->type: " << std::dec << header->type;
    SNAP_LOG(DEBUG) << "Daemon: msg->flags: " << std::dec << header->flags;

    if (!ProcessRequest(header)) {
        if (header->type != DM_USER_RESP_ERROR) {
            SendError();
        }
        return false;
    }
    return true;
}

bool DmUserBlockServer::ProcessRequest(dm_user_header* header) {
    // Use the same header buffer as the response header.
    int request_type = header->type;
    header->type = DM_USER_RESP_SUCCESS;
    header_response_ = true;

    // Reset the output buffer.
    buffer_.ResetBufferOffset();

    switch (request_type) {
        case DM_USER_REQ_MAP_READ:
            return delegate_->RequestSectors(header->sector, header->len);

        case DM_USER_REQ_MAP_WRITE:
            // We should not get any write request to dm-user as we mount all
            // partitions as read-only.
            SNAP_LOG(ERROR) << "Unexpected write request from dm-user";
            return false;

        default:
            SNAP_LOG(ERROR) << "Unexpected request from dm-user: " << request_type;
            return false;
    }
}

void* DmUserBlockServer::GetResponseBuffer(size_t size, size_t to_write) {
    return buffer_.AcquireBuffer(size, to_write);
}

bool DmUserBlockServer::SendBufferedIo() {
    return WriteDmUserPayload(buffer_.GetPayloadBytesWritten());
}

void DmUserBlockServer::SendError() {
    struct dm_user_header* header = buffer_.GetHeaderPtr();
    header->type = DM_USER_RESP_ERROR;
    // This is an issue with the dm-user interface. There
    // is no way to propagate the I/O error back to dm-user
    // if we have already communicated the header back. Header
    // is responded once at the beginning; however I/O can
    // be processed in chunks. If we encounter an I/O error
    // somewhere in the middle of the processing, we can't communicate
    // this back to dm-user.
    //
    // TODO: Fix the interface
    CHECK(header_response_);

    WriteDmUserPayload(0);
}

bool DmUserBlockServer::WriteDmUserPayload(size_t size) {
    size_t payload_size = size;
    void* buf = buffer_.GetPayloadBufPtr();
    if (header_response_) {
        payload_size += sizeof(struct dm_user_header);
        buf = buffer_.GetBufPtr();
    }

    if (!android::base::WriteFully(ctrl_fd_, buf, payload_size)) {
        SNAP_PLOG(ERROR) << "Write to dm-user failed size: " << payload_size;
        return false;
    }

    // After the first header is sent in response to a request, we cannot
    // send any additional headers.
    header_response_ = false;

    // Reset the buffer for use by the next request.
    buffer_.ResetBufferOffset();
    return true;
}

DmUserBlockServerOpener::DmUserBlockServerOpener(const std::string& misc_name,
                                                 const std::string& dm_user_path)
    : misc_name_(misc_name), dm_user_path_(dm_user_path) {}

std::unique_ptr<IBlockServer> DmUserBlockServerOpener::Open(IBlockServer::Delegate* delegate,
                                                            size_t buffer_size) {
    unique_fd fd(open(dm_user_path_.c_str(), O_RDWR | O_CLOEXEC));
    if (fd < 0) {
        SNAP_PLOG(ERROR) << "Could not open dm-user path: " << dm_user_path_;
        return nullptr;
    }
    return std::make_unique<DmUserBlockServer>(misc_name_, std::move(fd), delegate, buffer_size);
}

std::shared_ptr<IBlockServerOpener> DmUserBlockServerFactory::CreateOpener(
        const std::string& misc_name) {
    auto dm_path = "/dev/dm-user/" + misc_name;
    return std::make_shared<DmUserBlockServerOpener>(misc_name, dm_path);
}

}  // namespace snapshot
}  // namespace android
