// 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::io::Error;
use std::collections::HashMap;
use std::sync::{Mutex, Once};
use std::mem;
use libc::{self, c_int, c_void, sigset_t, siginfo_t};
use libc::{signal, sigprocmask, sigaction, sigemptyset, sigfillset, raise};
use libc::{SIG_SETMASK, SA_SIGINFO, SIG_ERR, SIG_DFL};
use crate::sgx_types::{sgx_enclave_id_t, sgx_status_t};

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

pub const SIGRTMIN: c_int = 32;
pub const SIGRTMAX: c_int = 64;
pub const NSIG: c_int = SIGRTMAX + 1;

extern "C" {
    fn t_signal_handler_ecall(eid: sgx_enclave_id_t,
                              retval: *mut c_int,
                              info: *const siginfo_t) -> sgx_status_t;
}

#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct SigNum(i32);

impl SigNum {

    pub fn from_raw(signo: i32) -> Option<SigNum> {
        if signo <= 0 || signo >= NSIG {
            None
        } else {
            Some(SigNum(signo))
        }
    }
    pub unsafe fn from_raw_uncheck(signo: i32) -> SigNum {
        SigNum(signo)
    }
    pub fn raw(&self) -> i32 { self.0 }
}

#[derive(Copy, Clone)]
pub struct SigSet(sigset_t);

impl SigSet {

    pub fn new() -> SigSet {
        let set = unsafe {
            let mut set: sigset_t = mem::zeroed();
            sigemptyset(&mut set as *mut sigset_t);
            set
        };
        SigSet(set)
    }
    pub fn fill(&mut self) {
        unsafe {
            sigfillset(&mut self.0 as *mut sigset_t);
        }
    }
    pub unsafe fn from_raw(set: sigset_t) -> SigSet { SigSet(set) }
    pub fn raw(&self) -> sigset_t { self.0 }
}

struct GlobalData {
    signal_dispatcher: SignalDispatcher,
}

impl GlobalData {

    fn get() -> &'static GlobalData {
        unsafe { GLOBAL_DATA.as_ref().unwrap() }
    }
    fn ensure() -> &'static GlobalData {
        DISPATCHER_INIT.call_once(|| unsafe {
            GLOBAL_DATA = Some(GlobalData {
                signal_dispatcher: SignalDispatcher::new(),
            });
        });
        Self::get()
    }
}

struct SignalDispatcher {
    signal_set: Mutex<HashMap<SigNum, sgx_enclave_id_t>>,
}

impl SignalDispatcher {

    pub fn new () -> SignalDispatcher {
        SignalDispatcher {
            signal_set: Mutex::new(HashMap::new()),
        }
    }

    pub fn register_signal(&self, signo: SigNum, enclave_id: sgx_enclave_id_t) -> Option<sgx_enclave_id_t> {
         // Block all signals when registering a signal handler to avoid deadlock.
        let mut mask = SigSet::new();
        let oldmask = SigSet::new();
        mask.fill();

        unsafe { sigprocmask(SIG_SETMASK, &mask.raw(), &mut oldmask.raw() as *mut sigset_t); }
        let old = self.signal_set
            .lock()
            .unwrap()
            .insert(signo, enclave_id);
        unsafe { sigprocmask(SIG_SETMASK, &oldmask.raw(), 0 as *mut sigset_t); }
        old
    }

    pub fn get_eid_for_signal(&self, signo: SigNum) -> Option<sgx_enclave_id_t> {
        self.signal_set
            .lock()
            .unwrap()
            .get(&signo)
            .copied()
    }

    pub fn deregister_all_signals_for_eid(&self, eid: sgx_enclave_id_t) {
        let mut mask = SigSet::new();
        let oldmask = SigSet::new();
        mask.fill();

        unsafe { sigprocmask(SIG_SETMASK, &mask.raw(), &mut oldmask.raw() as *mut sigset_t); }
        // If this enclave has registered any signals, deregister them and set the
        // signal handler to the default one.
        self.signal_set
            .lock()
            .unwrap()
            .retain(|&signum, &mut v| {
                if v == eid {
                    unsafe {
                        if signal(signum.raw(), SIG_DFL) == SIG_ERR {
                        }
                    }
                }
                v != eid
            });
        unsafe { sigprocmask(SIG_SETMASK, &oldmask.raw(), 0 as *mut sigset_t); }
    }

    unsafe fn handle_signal(
        &self,
        signo: SigNum,
        info: &siginfo_t,
        _context: *const c_void,
    ) -> c_int {
        let mut retval: c_int = 0;
        let eid = match self.get_eid_for_signal(signo) {
            Some(eid) => eid,
            None => return -1,
        };

        let result = t_signal_handler_ecall(
            eid,
            &mut retval as *mut c_int,
            info as *const siginfo_t,
        );
        if result != sgx_status_t::SGX_SUCCESS {
            return -1;
        }
        retval
    }
}

pub fn deregister_all_signals_for_eid(enclave_id: sgx_enclave_id_t) {
    let global = GlobalData::ensure();
    global.signal_dispatcher.deregister_all_signals_for_eid(enclave_id);
}

extern "C" fn handle_signal_entry(signum: c_int, info: *const siginfo_t, ucontext: *const c_void) {
    let signo = SigNum::from_raw(signum);
    if info.is_null() || signo.is_none() {
        return;
    }

    unsafe {
        GlobalData::get().signal_dispatcher
            .handle_signal(signo.unwrap(), &(*info), ucontext);
    }
}

#[no_mangle]
pub extern "C" fn u_sigaction_ocall(
    error: * mut c_int,
    signum: c_int,
    act: *const sigaction,
    oldact: *mut sigaction,
    enclave_id: sgx_enclave_id_t,
) -> c_int {
    let mut errno = 0;
    let signo = SigNum::from_raw(signum);
    if signo.is_none() || act.is_null() {
        if  !error.is_null() {
            unsafe {  *error = libc::EINVAL; }
        }
        return -1;
    }

    let e_act = unsafe { &*act };
    let ret = if e_act.sa_sigaction == 0 {
        let global = GlobalData::ensure();
        global.signal_dispatcher.register_signal(signo.unwrap(), enclave_id);

        type FnSaSigaction = extern "C" fn(c_int, *const siginfo_t, *const c_void);
        let new_act = sigaction {
            sa_sigaction: unsafe { mem::transmute::<FnSaSigaction, usize>(handle_signal_entry) },
            // Set the flag so that sa_sigaction is registered as the signal handler
            // instead of sa_handler.
            sa_flags: e_act.sa_flags | SA_SIGINFO,
            sa_mask: e_act.sa_mask,
            sa_restorer: None,
        };
        let mut old_act: sigaction = unsafe { mem::zeroed() };
        unsafe { sigaction(signum, &new_act, &mut old_act as *mut sigaction) }
    } else {
       unsafe { sigaction(signum, act as *const sigaction, oldact) }
    };

    if ret < 0 {
        errno = Error::last_os_error().raw_os_error().unwrap_or(0);
    }
    if !error.is_null() {
        unsafe { *error = errno; }
    }
    ret
}

#[no_mangle]
pub extern "C" fn u_sigprocmask_ocall(
    error: *mut c_int,
    signum: c_int,
    set: *const sigset_t,
    oldset: *mut sigset_t,
) -> c_int {
    let mut errno = 0;
    let ret = unsafe { sigprocmask(signum, set, oldset) };
    if ret < 0 {
        errno = Error::last_os_error().raw_os_error().unwrap_or(0);
    }
    if !error.is_null() {
        unsafe { *error = errno; }
    }
    ret
}

#[no_mangle]
pub extern "C" fn u_raise_ocall(signum: c_int) -> c_int {
    unsafe { raise(signum) }
}

#[no_mangle]
pub extern "C" fn u_signal_clear_ocall(eid: sgx_enclave_id_t) {
    deregister_all_signals_for_eid(eid);
}
