// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <assert.h>
#include <ctype.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>

#include <zircon/device/device.h>
#include <zircon/device/vfs.h>

#include <zircon/syscalls.h>
#include <fdio/debug.h>
#include <fdio/vfs.h>
#include <fbl/ref_ptr.h>

#define MXDEBUG 0

#include "blobstore-private.h"

using digest::Digest;

namespace blobstore {

VnodeBlob::~VnodeBlob() {
    blobstore_->ReleaseBlob(this);
    if (blob_ != nullptr) {
        block_fifo_request_t request;
        request.txnid = blobstore_->TxnId();
        request.vmoid = vmoid_;
        request.opcode = BLOCKIO_CLOSE_VMO;
        blobstore_->Txn(&request, 1);
    }
}

zx_status_t VnodeBlob::ValidateFlags(uint32_t flags) {
    if ((flags & O_DIRECTORY) && !IsDirectory()) {
        return ZX_ERR_NOT_DIR;
    }

    switch (flags & O_ACCMODE) {
    case O_WRONLY:
    case O_RDWR:
        if (IsDirectory()) {
            return ZX_ERR_NOT_FILE;
        } else if (GetState() != kBlobStateEmpty) {
            return ZX_ERR_ACCESS_DENIED;
        }
    }
    return ZX_OK;
}

zx_status_t VnodeBlob::Readdir(fs::vdircookie_t* cookie, void* dirents, size_t len,
                               size_t* out_actual) {
    if (!IsDirectory()) {
        return ZX_ERR_NOT_DIR;
    }

    return blobstore_->Readdir(cookie, dirents, len, out_actual);
}

zx_status_t VnodeBlob::Read(void* data, size_t len, size_t off, size_t* out_actual) {
    if (IsDirectory()) {
        return ZX_ERR_NOT_FILE;
    }

    return ReadInternal(data, len, off, out_actual);
}

zx_status_t VnodeBlob::Write(const void* data, size_t len, size_t offset,
                             size_t* out_actual) {
    if (IsDirectory()) {
        return ZX_ERR_NOT_FILE;
    }
    zx_status_t status = WriteInternal(data, len, out_actual);
    return status;
}

zx_status_t VnodeBlob::Append(const void* data, size_t len, size_t* out_end,
                              size_t* out_actual) {
    zx_status_t status = Write(data, len, bytes_written_, out_actual);
    *out_actual = bytes_written_;
    return status;
}

zx_status_t VnodeBlob::Lookup(fbl::RefPtr<fs::Vnode>* out, fbl::StringPiece name) {
    assert(memchr(name.data(), '/', name.length()) == nullptr);
    if (name == "." && IsDirectory()) {
        // Special case: Accessing root directory via '.'
        *out = fbl::RefPtr<VnodeBlob>(this);
        return ZX_OK;
    }

    if (!IsDirectory()) {
        return ZX_ERR_NOT_SUPPORTED;
    }

    zx_status_t status;
    Digest digest;
    if ((status = digest.Parse(name.data(), name.length())) != ZX_OK) {
        return status;
    }
    fbl::RefPtr<VnodeBlob> vn;
    if ((status = blobstore_->LookupBlob(digest, &vn)) < 0) {
        return status;
    }
    *out = fbl::move(vn);
    return ZX_OK;
}

zx_status_t VnodeBlob::Getattr(vnattr_t* a) {
    memset(a, 0, sizeof(vnattr_t));
    a->mode = (IsDirectory() ? V_TYPE_DIR : V_TYPE_FILE) | V_IRUSR;
    a->inode = 0;
    a->size = IsDirectory() ? 0 : SizeData();
    a->blksize = kBlobstoreBlockSize;
    a->blkcount = blobstore_->GetNode(map_index_)->num_blocks *
                  (kBlobstoreBlockSize / VNATTR_BLKSIZE);
    a->nlink = 1;
    a->create_time = 0;
    a->modify_time = 0;
    return ZX_OK;
}

zx_status_t VnodeBlob::Create(fbl::RefPtr<fs::Vnode>* out, fbl::StringPiece name, uint32_t mode) {
    assert(memchr(name.data(), '/', name.length()) == nullptr);
    if (!IsDirectory()) {
        return ZX_ERR_NOT_SUPPORTED;
    }

    Digest digest;
    zx_status_t status;
    if ((status = digest.Parse(name.data(), name.length())) != ZX_OK) {
        return status;
    }
    fbl::RefPtr<VnodeBlob> vn;
    if ((status = blobstore_->NewBlob(digest, &vn)) != ZX_OK) {
        return status;
    }
    *out = fbl::move(vn);
    return ZX_OK;
}

constexpr const char kFsName[] = "blobstore";

zx_status_t VnodeBlob::Ioctl(uint32_t op, const void* in_buf, size_t in_len, void* out_buf,
                             size_t out_len, size_t* out_actual) {
    switch (op) {
    case IOCTL_VFS_QUERY_FS: {
        if (out_len < sizeof(vfs_query_info_t) + strlen(kFsName)) {
            return ZX_ERR_INVALID_ARGS;
        }
        vfs_query_info_t* info = static_cast<vfs_query_info_t*>(out_buf);
        info->total_bytes = blobstore_->info_.block_count * blobstore_->info_.block_size;
        info->used_bytes = blobstore_->info_.alloc_block_count * blobstore_->info_.block_size;
        info->total_nodes = blobstore_->info_.inode_count;
        info->used_nodes = blobstore_->info_.alloc_inode_count;
        memcpy(info->name, kFsName, strlen(kFsName));
        *out_actual = sizeof(vfs_query_info_t) + strlen(kFsName);
        return ZX_OK;
    }
    case IOCTL_VFS_UNMOUNT_FS: {
        zx_status_t status = Sync();
        if (status != ZX_OK) {
            FS_TRACE_ERROR("blobstore unmount failed to sync; unmounting anyway: %d\n", status);
        }
        *out_actual = 0;
        return blobstore_->Unmount();
    }
#ifdef __Fuchsia__
    case IOCTL_VFS_GET_DEVICE_PATH: {
        ssize_t len = ioctl_device_get_topo_path(blobstore_->blockfd_, static_cast<char*>(out_buf), out_len);

        if ((ssize_t)out_len < len) {
            return ZX_ERR_INVALID_ARGS;
        }

        if (len >= 0) {
            *out_actual = len;
        }
        return len > 0 ? ZX_OK : static_cast<zx_status_t>(len);
    }
#endif
    default: {
        return ZX_ERR_NOT_SUPPORTED;
    }
    }
}

zx_status_t VnodeBlob::Truncate(size_t len) {
    if (IsDirectory()) {
        return ZX_ERR_NOT_SUPPORTED;
    }

    return SpaceAllocate(len);
}

zx_status_t VnodeBlob::Unlink(fbl::StringPiece name, bool must_be_dir) {
    assert(memchr(name.data(), '/', name.length()) == nullptr);
    if (!IsDirectory()) {
        return ZX_ERR_NOT_SUPPORTED;
    }

    zx_status_t status;
    Digest digest;
    fbl::RefPtr<VnodeBlob> out;
    if ((status = digest.Parse(name.data(), name.length())) != ZX_OK) {
        return status;
    } else if ((status = blobstore_->LookupBlob(digest, &out)) < 0) {
        return status;
    }
    out->QueueUnlink();
    return ZX_OK;
}

zx_status_t VnodeBlob::Mmap(int flags, size_t len, size_t* off, zx_handle_t* out) {
    if (IsDirectory()) {
        return ZX_ERR_NOT_SUPPORTED;
    }
    if (flags & FDIO_MMAP_FLAG_WRITE) {
        return ZX_ERR_NOT_SUPPORTED;
    }

    zx_rights_t rights = ZX_RIGHT_TRANSFER | ZX_RIGHT_MAP;
    rights |= (flags & FDIO_MMAP_FLAG_READ) ? ZX_RIGHT_READ : 0;
    rights |= (flags & FDIO_MMAP_FLAG_EXEC) ? ZX_RIGHT_EXECUTE : 0;
    return CopyVmo(rights, out);
}

zx_status_t VnodeBlob::Sync() {
    // TODO(smklein): For now, this is a no-op, but it will change
    // once the kBlobFlagSync flag is in use.
    return ZX_OK;
}

} // namespace blobstore
