// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License..

use std::enclave::get_enclave_id;
use std::sync::{Once, Arc, SgxMutex};
use std::rt::*;
use std::mem;
use std::io::Error;
use sgx_libc::set_errno;
use sgx_libc::{EINVAL, ESGX};
use sgx_libc::{sighandler_t, sigset_t, siginfo_t, sigemptyset, sigaction};
use sgx_libc::{
    SIGSTOP, SIGKILL, SIGILL, SIGSEGV, SIGFPE, SIGBUS,
    SIGTRAP, SIG_DFL, SIG_ERR, SIG_BLOCK, SIG_UNBLOCK,
    SIG_SETMASK, SA_RESETHAND
};
use sgx_libc::ocall::{sigaction, sigprocmask, raise};
use sgx_types::{c_int, c_void, sgx_status_t, sgx_enclave_id_t, SysResult};
use crate::manager::{self, ActionId, SignalManager, SigNum, SigSet};

pub const FORBIDDEN: &[c_int] = FORBIDDEN_IMPL;
const FORBIDDEN_IMPL: &[c_int] = &[SIGKILL,
                                   SIGSTOP,
                                   SIGILL,
                                   SIGFPE,
                                   SIGSEGV,
                                   SIGBUS,
                                   SIGTRAP];

#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct SignalId {
    signal: SigNum,
    action: ActionId,
}

struct GlobalData {
   signal_manager: SignalManager,
   signal_action_lock: SgxMutex<()>,
}

static mut GLOBAL_DATA: Option<GlobalData> = None;
static MANAGER_INIT: Once = Once::new();

extern "C" {
    pub fn u_signal_clear_ocall(enclave_id: sgx_enclave_id_t) -> sgx_status_t;
}

impl GlobalData {
    // add code here
    fn get() -> &'static Self {
        unsafe { GLOBAL_DATA.as_ref().unwrap() }
    }

    fn ensure() -> &'static Self {
        MANAGER_INIT.call_once(|| unsafe {
            GLOBAL_DATA = Some(GlobalData {
                signal_manager: SignalManager::new(),
                signal_action_lock: SgxMutex::new(()),
            });

            let _r = at_exit(|| Self::clear() );
        });
        Self::get()
    }

    fn clear() {
        if !Self::get().signal_manager.is_action_empty() {
            //ocall
            unsafe { u_signal_clear_ocall(get_enclave_id()) };
        }
    }
}

#[no_mangle]
pub extern "C" fn t_signal_handler_ecall(info: *const siginfo_t) -> c_int {
    if info.is_null() {
        return -1;
    }
    let si_info = unsafe { &*(info) };
    let global = GlobalData::get();
    let mask = manager::get_block_mask();
    // If the signal is blocked and still passed into the enclave. The signal
    // masks inside the enclave is out of sync with the untrusted signal mask.
    unsafe {
        let signo = SigNum::from_raw_uncheck(si_info.si_signo);
        if mask.is_member(signo) {
           -1
        } else {
            global.signal_manager.handler(
                si_info.si_signo,
                info as *const siginfo_t,
                0 as *const c_void);
            0
        }
    }
}

fn native_sigaction(signo: SigNum, act: &sigaction, oldact: &mut sigaction) -> c_int {
    let global = GlobalData::ensure();
    let mut mask = SigSet::new();
    let old_mask = SigSet::new();

    mask.fill();

    // Guards sigaction calls. This is to ensure that signal handlers are not
    // overwritten between the time sigaction gets |oldact| and sets |act|.
    {
        let _guard = global.signal_action_lock.lock();
        if let Some(t) = global.signal_manager.get_action(signo) {
            *oldact = t.get_act();
        } else {
            oldact.sa_sigaction = SIG_DFL;
        }

        rsgx_sigprocmask(SIG_SETMASK, &mask.raw(), &mut old_mask.raw());
        global.signal_manager.set_action(signo, act);
        rsgx_sigprocmask(SIG_SETMASK, &old_mask.raw(), &mut mask.raw());
    }

    let new_act = sigaction {
        sa_sigaction: 0,
        sa_mask: act.sa_mask,
        sa_flags: act.sa_flags,
        sa_restorer: None,
    };
    if (new_act.sa_flags & SA_RESETHAND) != 0 {
        global.signal_manager.set_reset_on_handle(signo);
    }

    unsafe {
        sigaction(
            signo.raw(),
            &new_act,
            oldact as *mut sigaction,
            get_enclave_id(),
        )
    }
}

fn native_sigaction_impl<F>(
    signo: SigNum,
    act: &sigaction,
    oldact: &mut sigaction,
    f: Arc<F>,
) -> SysResult<ActionId>
where
    F: Fn(&siginfo_t) + Sync + Send + 'static,
{
    let global = GlobalData::ensure();
    let mut mask = SigSet::new();
    let old_mask = SigSet::new();

    mask.fill();

    // Guards sigaction calls. This is to ensure that signal handlers are not
    // overwritten between the time sigaction gets |oldact| and sets |act|.
    let (exist, action_id) = {
        let _guard = global.signal_action_lock.lock();
        let exist = if let Some(t) = global.signal_manager.get_action(signo) {
            *oldact = t.get_act();
            true
        } else {
            oldact.sa_sigaction = SIG_DFL;
            false
        };

        rsgx_sigprocmask(SIG_SETMASK, &mask.raw(), &mut old_mask.raw());
        let action_id = global.signal_manager.set_action_impl(signo, act, f);
        rsgx_sigprocmask(SIG_SETMASK, &old_mask.raw(), &mut mask.raw());
        (exist, action_id)
    };

    if exist {
        return Ok(action_id);
    }

    let new_act = sigaction {
        sa_sigaction: 0,
        sa_mask: act.sa_mask,
        sa_flags: act.sa_flags,
        sa_restorer: None,
    };
    if (new_act.sa_flags & SA_RESETHAND) != 0 {
        global.signal_manager.set_reset_on_handle(signo);
    }

    let result = unsafe {
        sigaction(
            signo.raw(),
            &new_act,
            oldact as *mut sigaction,
            get_enclave_id(),
        )
    };
    if result == 0 {
        Ok(action_id)
    } else {
        Err(result)
    }
}

pub fn rsgx_sigaction(signum: c_int, act: &sigaction, oldact: &mut sigaction) -> c_int {
    if FORBIDDEN.contains(&signum) {
        set_errno(EINVAL);
        return -1;
    }

    let eid = get_enclave_id();
    if eid == 0 {
        set_errno(ESGX);
        return -1;
    }

    let signo = match SigNum::from_raw(signum) {
        Some(signo) => signo,
        None => {
            set_errno(EINVAL);
            return -1;
        }
    };
    native_sigaction(signo, act, oldact)
}

pub fn rsgx_signal(signum: c_int, handler: sighandler_t) -> sighandler_t {
    let mut act: sigaction = unsafe { mem::zeroed() };
    let mut oldact: sigaction = unsafe { mem::zeroed() };
    act.sa_sigaction = handler;
    unsafe { sigemptyset(&mut act.sa_mask as *mut sigset_t) };
    if rsgx_sigaction(signum, &act, &mut oldact) != 0  {
        // Errno is set by sigaction.
        return SIG_ERR;
    }
    oldact.sa_sigaction
}

pub fn rsgx_sigprocmask(how: c_int, set: &sigset_t, oldset: &mut sigset_t) -> c_int {
    if how != SIG_BLOCK && how != SIG_UNBLOCK && how != SIG_SETMASK {
        set_errno(EINVAL);
        return -1;
    }

    let mut signals_to_block = SigSet::new();
    let mut signals_to_unblock = SigSet::new();

    *oldset = manager::get_block_mask().raw();
    let newset = unsafe { SigSet::from_raw(*set) };

    if how == SIG_BLOCK || how == SIG_SETMASK {
        signals_to_block = newset;
    }
    if how == SIG_UNBLOCK {
        signals_to_unblock = newset;
    } else if how == SIG_SETMASK {
        signals_to_unblock = newset.complement();
    }
    // Unblock signals inside the enclave before unblocking signals on the host.
    // |oldset| is already filled with the signal mask inside the enclave.
    manager::unblock(&signals_to_unblock);
    let result = unsafe {
        sigprocmask(
            how,
            set as *const sigset_t,
            0 as *mut sigset_t,
        )
    };
    // Block signals inside the enclave after the host.
    manager::block(&signals_to_block);
    result
}

pub fn rsgx_raise(signum: c_int) -> c_int {
    unsafe { raise(signum) }
}

pub fn register<F>(signal: c_int, action: F) -> Result<SignalId, Error>
where
    F: Fn() + Sync + Send + 'static,
{
    register_sigaction_impl(signal, move |_: &_| action())
}

pub fn register_sigaction<F>(signal: c_int, action: F) -> Result<SignalId, Error>
where
    F: Fn(&siginfo_t) + Sync + Send + 'static,
{
    register_sigaction_impl(signal, action)
}

fn register_sigaction_impl<F>(signal: c_int, action: F) -> Result<SignalId, Error>
where
    F: Fn(&siginfo_t) + Sync + Send + 'static,
{
    register_impl(signal, action)
}

fn register_impl<F>(signal: c_int, action: F) -> Result<SignalId, Error>
where
    F: Fn(&siginfo_t) + Sync + Send + 'static,
{
    if FORBIDDEN.contains(&signal) {
        set_errno(EINVAL);
        return Err(Error::from_raw_os_error(EINVAL));
    }

    let eid = get_enclave_id();
    if eid == 0 {
        set_errno(ESGX);
        return Err(Error::from_sgx_error(sgx_status_t::SGX_ERROR_INVALID_ENCLAVE_ID));
    }

    let signo = match SigNum::from_raw(signal) {
        Some(signo) => signo,
        None => {
            set_errno(EINVAL);
            return Err(Error::from_raw_os_error(EINVAL));
        }
    };

    let act: sigaction = unsafe { mem::zeroed() };
    let mut oldact: sigaction = unsafe { mem::zeroed() };

    native_sigaction_impl(
        signo,
        &act,
        &mut oldact,
        Arc::from(action),
    )
    .map(|action_id|
        SignalId {
            signal: signo,
            action: action_id,
        }
    )
    .map_err(|err|
        Error::from_raw_os_error(err)
    )
}

pub fn unregister(id: SignalId) -> bool {
    let globals = GlobalData::ensure();
    globals.signal_manager.remove_action(id.signal, id.action)
}

pub fn unregister_signal(signal: c_int) -> bool {
    let globals = GlobalData::ensure();
    let signo = unsafe { SigNum::from_raw_uncheck(signal) };
    globals.signal_manager.clear_action(signo)
}

pub fn raise_signal(signal: c_int) -> bool {
   rsgx_raise(signal) == 0
}
