/*
 * Copyright 2020 Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <gtest/gtest.h>

#include <csetjmp>
#include <csignal>
#include <cstdlib>
#include <cstring>
#include <iostream>

#include <gem5/asm/generic/m5ops.h>

#include "args.hh"
#include "call_type.hh"
#include "call_type/verify_inst.hh"
#include "dispatch_table.hh"

class DefaultCallType : public CallType
{
  private:
    DispatchTable dt;

  public:
    DefaultCallType() : CallType("default") {}

    bool init_called = false;
    void init() override { init_called = true; }

    bool isDefault() const override { return true; }
    void printDesc(std::ostream &os) const override {}
    const DispatchTable &getDispatch() const override { return dt; }
};

DefaultCallType defaultCallType;

class InstCallTypeTest : public testing::Test
{
  protected:
    CallType *ct = nullptr;
};

TEST_F(InstCallTypeTest, EmptyArgs)
{
    // Inst should not be selected if there are no arguments.
    Args empty({});
    defaultCallType.init_called = false;
    ct = CallType::detect(empty);
    EXPECT_EQ(ct, &defaultCallType);
    EXPECT_TRUE(defaultCallType.init_called);
}

TEST_F(InstCallTypeTest, NotAnyArg)
{
    // Inst should not be selected if --inst isn't the first argument.
    Args one_arg({"one"});
    defaultCallType.init_called = false;
    ct = CallType::detect(one_arg);
    EXPECT_EQ(ct, &defaultCallType);
    EXPECT_TRUE(defaultCallType.init_called);
}

TEST_F(InstCallTypeTest, FirstArg)
{
    // Inst should be selected if --inst is the first argument.
    Args selected({"--inst"});
    defaultCallType.init_called = false;
    ct = CallType::detect(selected);
    EXPECT_NE(ct, &defaultCallType);
    EXPECT_NE(ct, nullptr);
    EXPECT_FALSE(defaultCallType.init_called);
}

TEST_F(InstCallTypeTest, ExtraArg)
{
    Args extra({"--inst", "foo"});
    defaultCallType.init_called = false;
    ct = CallType::detect(extra);
    EXPECT_NE(ct, &defaultCallType);
    EXPECT_NE(ct, nullptr);
    EXPECT_FALSE(defaultCallType.init_called);
}

TEST_F(InstCallTypeTest, NotFirstArg)
{
    // Inst should not be selected if --inst isn't first.
    Args not_first({"foo", "--inst"});
    defaultCallType.init_called = false;
    ct = CallType::detect(not_first);
    EXPECT_EQ(ct, &defaultCallType);
    EXPECT_TRUE(defaultCallType.init_called);
}

sigjmp_buf interceptEnv;
siginfo_t interceptSiginfo;

void
sigillHandler(int sig, siginfo_t *info, void *ucontext)
{
    std::memcpy(&interceptSiginfo, info, sizeof(interceptSiginfo));
    siglongjmp(interceptEnv, 1);
}

TEST(InstCallType, Sum)
{
    // Get the inst call type, which is in an anonymous namespace.
    Args args({"--inst"});
    CallType *inst_call_type = CallType::detect(args);
    EXPECT_NE(inst_call_type, nullptr);

    // Get the dispatch table associated with it.
    const auto &dt = inst_call_type->getDispatch();

    // Determine if we're running within gem5 by checking whether a flag is
    // set in the environment.
    bool in_gem5 = (std::getenv("RUNNING_IN_GEM5") != nullptr);
    if (in_gem5)
        std::cout << "In gem5, m5 ops should work." << std::endl;
    else
        std::cout << "Not in gem5, m5 ops won't work." << std::endl;

    // If it is, then we should be able to run the "sum" command.
    if (in_gem5) {
        EXPECT_EQ((*dt.m5_sum)(2, 2, 0, 0, 0, 0), 4);
        return;
    }

    // If not, then we'll need to try to catch the fall out from trying to run
    // an m5 op and verify that what we were trying looks correct.

    struct sigaction sigill_action;
    std::memset(&sigill_action, 0, sizeof(sigill_action));
    sigill_action.sa_sigaction = &sigillHandler;
    sigill_action.sa_flags = SA_SIGINFO | SA_RESETHAND;

    struct sigaction old_sigill_action;

    sigaction(SIGILL, &sigill_action, &old_sigill_action);

    if (!sigsetjmp(interceptEnv, 1)) {
        (*dt.m5_sum)(2, 2, 0, 0, 0, 0);
        sigaction(SIGILL, &old_sigill_action, nullptr);
        ADD_FAILURE() << "Didn't die when attempting to run \"sum\".";
        return;
    }

    // Back from siglongjump.
    auto &info = interceptSiginfo;

    EXPECT_EQ(info.si_signo, SIGILL);
    EXPECT_TRUE(info.si_code == ILL_ILLOPC || info.si_code == ILL_ILLOPN);

    // Do abi specific verification.
    abi_verify_inst(info, M5OP_SUM);
}
