// Copyright 2016 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 <stdio.h>
#include <threads.h>

#include <mx/channel.h>
#include <mx/event.h>
#include <mx/handle.h>
#include <mx/port.h>

#include <fbl/type_support.h>

#include <magenta/syscalls/port.h>

#include <unistd.h>
#include <unittest/unittest.h>

static bool basic_test() {
    // Test that"
    // 1- handles starts with the MX_SIGNAL_LAST_HANDLE active.
    // 2- the signal deactives on duplication.
    // 3- the signal comes back on closing the duplicated handle.
    // 4- the MX_SIGNAL_LAST_HANDLE cannot be touched with mx_object_signal().

    BEGIN_TEST;
    mx::event event;
    ASSERT_EQ(mx::event::create(0u, &event), MX_OK);
    mx_signals_t observed = 0u;
    EXPECT_EQ(
        event.wait_one(MX_SIGNAL_LAST_HANDLE, MX_TIME_INFINITE, &observed), MX_OK);
    EXPECT_EQ(observed, MX_SIGNAL_LAST_HANDLE);

    mx::event dup;
    EXPECT_EQ(event.duplicate(MX_RIGHT_SAME_RIGHTS, &dup), MX_OK);

    EXPECT_EQ(event.wait_one(MX_SIGNAL_LAST_HANDLE, 0u, &observed), MX_ERR_TIMED_OUT);
    EXPECT_EQ(observed, 0u);

    dup.reset();
    EXPECT_EQ(
        event.wait_one(MX_SIGNAL_LAST_HANDLE, MX_TIME_INFINITE, &observed), MX_OK);
    EXPECT_EQ(observed, MX_SIGNAL_LAST_HANDLE);

    EXPECT_EQ(event.signal(MX_SIGNAL_LAST_HANDLE, 0), MX_ERR_INVALID_ARGS);
    END_TEST;
}

static bool replace_test() {
    // Test that:
    // 1- replacing the handle keeps the MX_SIGNAL_LAST_HANDLE signal.
    // 2- replacing a duplicate does not spuriosly signal MX_SIGNAL_LAST_HANDLE.
    // 3- closing the replacement does signal MX_SIGNAL_LAST_HANDLE.
    // Note: we rely on a port to detect the edge transition, if any.

    BEGIN_TEST;
    mx::event old_ev;
    ASSERT_EQ(mx::event::create(0u, &old_ev), MX_OK);

    mx::event new_ev;
    EXPECT_EQ(old_ev.replace(MX_RIGHT_SAME_RIGHTS, &new_ev), MX_OK);

    mx_signals_t observed = 0u;
    EXPECT_EQ(
        new_ev.wait_one(MX_SIGNAL_LAST_HANDLE, MX_TIME_INFINITE, &observed), MX_OK);
    EXPECT_EQ(observed, MX_SIGNAL_LAST_HANDLE);

    mx::event dup;
    EXPECT_EQ(new_ev.duplicate(MX_RIGHT_SAME_RIGHTS, &dup), MX_OK);

    mx::port port;
    ASSERT_EQ(mx::port::create(0, &port), MX_OK);

    EXPECT_EQ(new_ev.wait_async(
        port, 1u, MX_SIGNAL_LAST_HANDLE, MX_WAIT_ASYNC_ONCE), MX_OK);

    mx_port_packet_t packet = {};
    EXPECT_EQ(port.wait(0ull, &packet, 0u), MX_ERR_TIMED_OUT);

    mx::event new_dup;
    EXPECT_EQ(dup.replace(MX_RIGHT_SAME_RIGHTS, &new_dup), MX_OK);
    EXPECT_EQ(port.wait(0ull, &packet, 0u), MX_ERR_TIMED_OUT);

    new_dup.reset();
    EXPECT_EQ(port.wait(MX_TIME_INFINITE, &packet, 0u), MX_OK);
    EXPECT_EQ(packet.type, MX_PKT_TYPE_SIGNAL_ONE);
    EXPECT_EQ(packet.signal.observed, MX_SIGNAL_LAST_HANDLE);

    END_TEST;
}

static bool channel_test() {
    // Test that:
    // 1- Sending/receiving a duplicated object never triggers MX_SIGNAL_LAST_HANDLE. The
    //    handle count is still 2, even though one handle is not accessible to
    //    any process.
    // 2- Sending an object and closing the send side of a channel does not trigger
    //    MX_SIGNAL_LAST_HANDLE.
    // 3- Closing the receive side of #2 does trigger MX_SIGNAL_LAST_HANDLE.

    BEGIN_TEST;
    mx::event event;
    ASSERT_EQ(mx::event::create(0u, &event), MX_OK);

    mx::channel channel[2];
    ASSERT_EQ(mx::channel::create(0u, &channel[0], &channel[1]), MX_OK);

    mx::port port;
    ASSERT_EQ(mx::port::create(0, &port), MX_OK);

    mx_handle_t dup_ev;
    EXPECT_EQ(mx_handle_duplicate(event.get(), MX_RIGHT_SAME_RIGHTS, &dup_ev), MX_OK);

    ASSERT_EQ(event.wait_async(
        port, 1u, MX_SIGNAL_LAST_HANDLE, MX_WAIT_ASYNC_ONCE), MX_OK);

    uint32_t actual_b;
    uint32_t actual_h;
    mx_port_packet_t packet = {};

    for (int ix = 0; ix != 4; ++ix) {
        ASSERT_EQ(channel[0].write(0u, nullptr, 0u, &dup_ev, 1u), MX_OK);
        dup_ev = 0u;

        EXPECT_EQ(port.wait(0ull, &packet, 0u), MX_ERR_TIMED_OUT);

        ASSERT_EQ(channel[1].read(
            0u, nullptr, 0, &actual_b, &dup_ev, 1u, &actual_h), MX_OK);

        EXPECT_EQ(port.wait(0ull, &packet, 0u), MX_ERR_TIMED_OUT);
    }

    ASSERT_EQ(channel[0].write(0u, nullptr, 0u, &dup_ev, 1u), MX_OK);

    channel[0].reset();
    EXPECT_EQ(port.wait(0ull, &packet, 0u), MX_ERR_TIMED_OUT);

    channel[1].reset();
    EXPECT_EQ(port.wait(MX_TIME_INFINITE, &packet, 0u), MX_OK);
    EXPECT_EQ(packet.type, MX_PKT_TYPE_SIGNAL_ONE);
    EXPECT_EQ(packet.signal.observed, MX_SIGNAL_LAST_HANDLE);

    END_TEST;
}

BEGIN_TEST_CASE(last_handle)
RUN_TEST(basic_test)
RUN_TEST(replace_test)
RUN_TEST(channel_test)
END_TEST_CASE(last_handle)

int main(int argc, char** argv) {
    bool success = unittest_run_all_tests(argc, argv);
    return success ? 0 : -1;
}
