// Copyright 2018 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 <lib/fidl/coding.h>
#include <lib/fidl/internal.h>
#include <lib/fidl/visitor.h>
#include <lib/fidl/walker.h>
#include <zircon/assert.h>
#include <zircon/compiler.h>
#include <zircon/syscalls.h>

#include <cstdint>
#include <cstdlib>
#include <limits>
#include <stdalign.h>

namespace {

struct Position;

struct StartingPoint {
    uint8_t* const addr;
    Position ToPosition() const;
};

struct Position {
    void* addr;
    Position operator+(uint32_t size) const {
        return Position{reinterpret_cast<void*>(reinterpret_cast<uint8_t*>(addr) + size)};
    }
    Position& operator+=(uint32_t size) {
        *this = *this + size;
        return *this;
    }
    template <typename T>
    constexpr T* Get(StartingPoint start) const {
        return reinterpret_cast<T*>(addr);
    }
};

Position StartingPoint::ToPosition() const {
    return Position{reinterpret_cast<void*>(addr)};
}

class FidlHandleCloser final : public fidl::Visitor<
                                   fidl::MutatingVisitorTrait, StartingPoint, Position> {
public:
    FidlHandleCloser(const char** out_error_msg)
        : out_error_msg_(out_error_msg) {}

    using StartingPoint = StartingPoint;

    using Position = Position;

    static constexpr bool kContinueAfterConstraintViolation = true;

    Status VisitPointer(Position ptr_position,
                        ObjectPointerPointer object_ptr_ptr,
                        uint32_t inline_size,
                        Position* out_position) {
        // Just follow the pointer into the child object
        *out_position = Position{*object_ptr_ptr};
        return Status::kSuccess;
    }

    Status VisitHandle(Position handle_position, HandlePointer handle) {
        // Close the handle and mark it as invalid
        zx_handle_close(*handle);
        *handle = ZX_HANDLE_INVALID;
        return Status::kSuccess;
    }

    Status VisitInternalPadding(Position padding_position, uint32_t padding_length) {
        return Status::kSuccess;
    }

    Status EnterEnvelope(Position envelope_position,
                         EnvelopePointer envelope,
                         const fidl_type_t* payload_type) {
        return Status::kSuccess;
    }

    Status LeaveEnvelope(Position envelope_position, EnvelopePointer envelope) {
        return Status::kSuccess;
    }

    void OnError(const char* error) {
        SetError(error);
    }

    zx_status_t status() const { return status_; }

private:
    void SetError(const char* error_msg) {
        if (status_ == ZX_OK) {
            status_ = ZX_ERR_INVALID_ARGS;
            if (out_error_msg_ != nullptr) {
                *out_error_msg_ = error_msg;
            }
        }
    }

    // Message state passed in to the constructor.
    const char** const out_error_msg_;
    zx_status_t status_ = ZX_OK;
};

} // namespace

zx_status_t fidl_close_handles(const fidl_type_t* type, void* value, const char** out_error_msg) {
    auto set_error = [&out_error_msg](const char* msg) {
        if (out_error_msg)
            *out_error_msg = msg;
    };
    if (value == nullptr) {
        set_error("Cannot close handles for null message");
        return ZX_ERR_INVALID_ARGS;
    }
    if (type == nullptr) {
        set_error("Cannot close handles for a null fidl type");
        return ZX_ERR_INVALID_ARGS;
    }

    FidlHandleCloser handle_closer(out_error_msg);
    fidl::Walk(handle_closer,
               type,
               StartingPoint{reinterpret_cast<uint8_t*>(value)});

    return handle_closer.status();
}

zx_status_t fidl_close_handles_msg(const fidl_type_t* type, const fidl_msg_t* msg,
                                   const char** out_error_msg) {
    return fidl_close_handles(type, msg->bytes, out_error_msg);
}
