// Copyright 2018 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT

#include <object/job_policy.h>

#include <fbl/algorithm.h>
#include <lib/unittest/unittest.h>

namespace {

static bool initial_state() {
    BEGIN_TEST;

    JobPolicy p;
    for (uint32_t pol = 0; pol < ZX_POL_MAX; ++pol) {
        EXPECT_EQ(ZX_POL_ACTION_ALLOW, p.QueryBasicPolicy(pol), "");
    }
    const TimerSlack slack = p.GetTimerSlack();
    EXPECT_TRUE(slack == TimerSlack::none(), "");

    END_TEST;
}

static bool add_basic_policy_absolute() {
    BEGIN_TEST;

    JobPolicy p;
    zx_policy_basic_t repeated[2]{{ZX_POL_NEW_ANY, ZX_POL_ACTION_DENY},
                                  {ZX_POL_NEW_ANY, ZX_POL_ACTION_DENY}};
    ASSERT_EQ(ZX_OK, p.AddBasicPolicy(ZX_JOB_POL_ABSOLUTE, repeated, 2), "");
    ASSERT_EQ(ZX_POL_ACTION_DENY, p.QueryBasicPolicy(ZX_POL_NEW_EVENT), "");

    zx_policy_basic_t conflicting[2]{{ZX_POL_NEW_ANY, ZX_POL_ACTION_DENY},
                                     {ZX_POL_NEW_ANY, ZX_POL_ACTION_ALLOW}};
    ASSERT_EQ(ZX_ERR_ALREADY_EXISTS, p.AddBasicPolicy(ZX_JOB_POL_ABSOLUTE, conflicting, 2), "");
    ASSERT_EQ(ZX_POL_ACTION_DENY, p.QueryBasicPolicy(ZX_POL_NEW_VMO), "");

    END_TEST;
}

static bool add_basic_policy_relative() {
    BEGIN_TEST;

    JobPolicy p;
    zx_policy_basic_t repeated[2]{{ZX_POL_NEW_ANY, ZX_POL_ACTION_DENY},
                                  {ZX_POL_NEW_ANY, ZX_POL_ACTION_DENY}};
    ASSERT_EQ(ZX_OK, p.AddBasicPolicy(ZX_JOB_POL_RELATIVE, repeated, 2), "");
    ASSERT_EQ(ZX_POL_ACTION_DENY, p.QueryBasicPolicy(ZX_POL_NEW_TIMER), "");

    zx_policy_basic_t conflicting[2]{{ZX_POL_NEW_ANY, ZX_POL_ACTION_DENY},
                                     {ZX_POL_NEW_ANY, ZX_POL_ACTION_ALLOW}};
    ASSERT_EQ(ZX_OK, p.AddBasicPolicy(ZX_JOB_POL_RELATIVE, conflicting, 2), "");
    ASSERT_EQ(ZX_POL_ACTION_DENY, p.QueryBasicPolicy(ZX_POL_NEW_FIFO), "");

    END_TEST;
}

// Test that AddBasicPolicy does not modify JobPolicy when it fails.
static bool add_basic_policy_unmodified_on_error() {
    BEGIN_TEST;

    JobPolicy p;
    zx_policy_basic_t policy[2]{{ZX_POL_NEW_VMO,
                                 ZX_POL_ACTION_ALLOW | ZX_POL_ACTION_EXCEPTION},
                                {ZX_POL_NEW_CHANNEL,
                                 ZX_POL_ACTION_KILL}};
    ASSERT_EQ(ZX_OK, p.AddBasicPolicy(ZX_JOB_POL_ABSOLUTE, policy, fbl::count_of(policy)), "");
    ASSERT_EQ(ZX_POL_ACTION_ALLOW | ZX_POL_ACTION_EXCEPTION,
              p.QueryBasicPolicy(ZX_POL_NEW_VMO), "");
    ASSERT_EQ(ZX_POL_ACTION_KILL, p.QueryBasicPolicy(ZX_POL_NEW_CHANNEL), "");

    const JobPolicy orig = p;

    zx_policy_basic_t new_policy{ZX_POL_NEW_ANY, UINT32_MAX};
    ASSERT_EQ(ZX_ERR_NOT_SUPPORTED, p.AddBasicPolicy(ZX_JOB_POL_ABSOLUTE, &new_policy, 1), "");
    ASSERT_TRUE(orig == p, "");

    new_policy = {ZX_POL_NEW_VMO, ZX_POL_ACTION_ALLOW};
    ASSERT_EQ(ZX_ERR_ALREADY_EXISTS, p.AddBasicPolicy(ZX_JOB_POL_ABSOLUTE, &new_policy, 1), "");
    ASSERT_TRUE(orig == p, "");

    END_TEST;
}

static bool add_basic_policy_deny_any() {
    BEGIN_TEST;

    JobPolicy p;
    zx_policy_basic_t policy{ZX_POL_NEW_ANY, ZX_POL_ACTION_DENY};
    ASSERT_EQ(ZX_OK, p.AddBasicPolicy(ZX_JOB_POL_ABSOLUTE, &policy, 1), "");
    ASSERT_EQ(ZX_POL_ACTION_DENY, p.QueryBasicPolicy(ZX_POL_NEW_VMO), "");
    ASSERT_EQ(ZX_POL_ACTION_DENY, p.QueryBasicPolicy(ZX_POL_NEW_CHANNEL), "");
    ASSERT_EQ(ZX_POL_ACTION_DENY, p.QueryBasicPolicy(ZX_POL_NEW_EVENT), "");
    ASSERT_EQ(ZX_POL_ACTION_DENY, p.QueryBasicPolicy(ZX_POL_NEW_EVENTPAIR), "");
    ASSERT_EQ(ZX_POL_ACTION_DENY, p.QueryBasicPolicy(ZX_POL_NEW_PORT), "");
    ASSERT_EQ(ZX_POL_ACTION_DENY, p.QueryBasicPolicy(ZX_POL_NEW_SOCKET), "");
    ASSERT_EQ(ZX_POL_ACTION_DENY, p.QueryBasicPolicy(ZX_POL_NEW_FIFO), "");
    ASSERT_EQ(ZX_POL_ACTION_DENY, p.QueryBasicPolicy(ZX_POL_NEW_TIMER), "");
    ASSERT_EQ(ZX_POL_ACTION_DENY, p.QueryBasicPolicy(ZX_POL_NEW_PROCESS), "");

    END_TEST;
}

static bool set_get_timer_slack() {
    BEGIN_TEST;

    JobPolicy p;
    p.SetTimerSlack({1200, TIMER_SLACK_EARLY});
    ASSERT_EQ(1200, p.GetTimerSlack().amount(), "");
    ASSERT_EQ(TIMER_SLACK_EARLY, p.GetTimerSlack().mode(), "");

    END_TEST;
}

} // namespace

UNITTEST_START_TESTCASE(job_policy_tests)
UNITTEST("initial_state", initial_state)
UNITTEST("add_basic_policy_absolute", add_basic_policy_absolute)
UNITTEST("add_basic_policy_relative", add_basic_policy_relative)
UNITTEST("add_basic_policy_unmodified_on_error", add_basic_policy_unmodified_on_error)
UNITTEST("add_basic_policy_deny_any", add_basic_policy_deny_any)
UNITTEST("set_get_timer_slack", set_get_timer_slack)
UNITTEST_END_TESTCASE(job_policy_tests, "job_policy", "JobPolicy tests");
