// Copyright 2021 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.

use crate::executive::ThreadContext;
use crate::syscalls::*;
use crate::types::*;

trait FromSyscallArg {
    fn from_arg(arg: u64) -> Self;
}
impl FromSyscallArg for i32 {
    fn from_arg(arg: u64) -> i32 {
        arg as i32
    }
}
impl FromSyscallArg for usize {
    fn from_arg(arg: u64) -> usize {
        arg as usize
    }
}
impl FromSyscallArg for u64 {
    fn from_arg(arg: u64) -> u64 {
        arg
    }
}
impl FromSyscallArg for UserAddress {
    fn from_arg(arg: u64) -> UserAddress {
        UserAddress::from(arg)
    }
}
trait IntoSyscallArg<T> {
    fn into_arg(self) -> T;
}

impl<T> IntoSyscallArg<T> for u64
where
    T: FromSyscallArg,
{
    fn into_arg(self) -> T {
        T::from_arg(self)
    }
}

macro_rules! syscall_match {
    {
        $ctx:ident; $syscall_number:ident; $args:ident;
        $($call:ident => $func:ident $arg_spec:tt,)*
    } => {
        match $syscall_number {
            $($call => syscall_match!(@call $ctx; $args; $func $arg_spec),)*
            _ => sys_unknown($ctx, $syscall_number),
        }
    };

    (@call $ctx:ident; $args:ident; $func:ident [0]) => ($func($ctx));
    (@call $ctx:ident; $args:ident; $func:ident [1]) => ($func($ctx, $args.0.into_arg()));
    (@call $ctx:ident; $args:ident; $func:ident [2]) => ($func($ctx, $args.0.into_arg(), $args.1.into_arg()));
    (@call $ctx:ident; $args:ident; $func:ident [3]) => ($func($ctx, $args.0.into_arg(), $args.1.into_arg(), $args.2.into_arg()));
    (@call $ctx:ident; $args:ident; $func:ident [4]) => ($func($ctx, $args.0.into_arg(), $args.1.into_arg(), $args.2.into_arg(), $args.3.into_arg()));
    (@call $ctx:ident; $args:ident; $func:ident [5]) => ($func($ctx, $args.0.into_arg(), $args.1.into_arg(), $args.2.into_arg(), $args.3.into_arg(), $args.4.into_arg()));
    (@call $ctx:ident; $args:ident; $func:ident [6]) => ($func($ctx, $args.0.into_arg(), $args.1.into_arg(), $args.2.into_arg(), $args.3.into_arg(), $args.4.into_arg(), $args.5.into_arg()));
}

pub fn dispatch_syscall(
    ctx: &mut ThreadContext,
    syscall_number: syscall_number_t,
    args: (u64, u64, u64, u64, u64, u64),
) -> Result<SyscallResult, Errno> {
    syscall_match! {
        ctx; syscall_number; args;
        SYS_WRITE => sys_write[3],
        SYS_FSTAT => sys_fstat[2],
        SYS_MMAP => sys_mmap[6],
        SYS_MPROTECT => sys_mprotect[3],
        SYS_BRK => sys_brk[1],
        SYS_PREAD64 => sys_pread64[4],
        SYS_WRITEV => sys_writev[3],
        SYS_ACCESS => sys_access[2],
        SYS_GETPID => sys_getpid[0],
        SYS_EXIT => sys_exit[1],
        SYS_UNAME => sys_uname[1],
        SYS_READLINK => sys_readlink[3],
        SYS_GETUID => sys_getuid[0],
        SYS_GETGID => sys_getgid[0],
        SYS_GETEUID => sys_geteuid[0],
        SYS_GETEGID => sys_getegid[0],
        SYS_FSTATFS => sys_fstatfs[2],
        SYS_SCHED_GETSCHEDULER => sys_sched_getscheduler[1],
        SYS_ARCH_PRCTL => sys_arch_prctl[2],
        SYS_EXIT_GROUP => sys_exit_group[1],
        SYS_OPENAT => sys_openat[4],
        SYS_GETRANDOM => sys_getrandom[3],
    }
}
