use std::{ffi::CString, marker::PhantomData};
use std::fmt;
use std::ptr;
use context::Context;
use rvalue::{RValue, ToRValue};
use rvalue;
use object::{ToObject, Object};
use object;
use field::Field;
use field;
use location::Location;
use location;

#[cfg(feature="master")]
#[derive(Clone, Copy, Debug)]
pub enum Visibility {
    Default,
    Hidden,
    Internal,
    Protected,
}

#[cfg(feature="master")]
impl Visibility {
    pub fn as_str(&self) -> &'static str {
        match *self {
            Visibility::Default => "default",
            Visibility::Hidden => "hidden",
            Visibility::Internal => "internal",
            Visibility::Protected => "protected",
        }
    }
}

#[cfg(feature="master")]
pub enum AttributeValue<'a> {
    #[allow(dead_code)]
    Int(i32),
    None,
    String(&'a str),
    IntArray(&'a [std::ffi::c_int]),
}

#[cfg(feature="master")]
#[derive(Clone, Copy, Debug)]
pub enum VarAttribute {
    Visibility(Visibility),
    Weak,
}

#[cfg(feature="master")]
impl VarAttribute {
    fn get_value(&self) -> AttributeValue {
        match *self {
            Self::Visibility(visibility) => AttributeValue::String(visibility.as_str()),
            Self::Weak => AttributeValue::None,
        }
    }

    fn to_sys(self) -> gccjit_sys::gcc_jit_variable_attribute {
        match self {
            VarAttribute::Visibility(_) => gccjit_sys::gcc_jit_variable_attribute::GCC_JIT_VARIABLE_ATTRIBUTE_VISIBILITY,
            VarAttribute::Weak => gccjit_sys::gcc_jit_variable_attribute::GCC_JIT_VARIABLE_ATTRIBUTE_WEAK,
        }
    }
}

#[derive(Clone, Copy, Debug)]
pub enum TlsModel {
    GlobalDynamic,
    LocalDynamic,
    InitialExec,
    LocalExec,
    None,
}

impl TlsModel {
    fn to_sys(self) -> gccjit_sys::gcc_jit_tls_model {
        use gccjit_sys::gcc_jit_tls_model::*;

        match self {
            TlsModel::GlobalDynamic => GCC_JIT_TLS_MODEL_GLOBAL_DYNAMIC,
            TlsModel::LocalDynamic => GCC_JIT_TLS_MODEL_LOCAL_DYNAMIC,
            TlsModel::InitialExec => GCC_JIT_TLS_MODEL_INITIAL_EXEC,
            TlsModel::LocalExec => GCC_JIT_TLS_MODEL_LOCAL_EXEC,
            TlsModel::None => GCC_JIT_TLS_MODEL_NONE,
        }
    }
}

/// An LValue in gccjit represents a value that has a concrete
/// location in memory. A LValue can be converted into an RValue
/// through the ToRValue trait.
/// It is also possible to get the address of an LValue.
#[derive(Copy, Clone, Eq, Hash, PartialEq)]
pub struct LValue<'ctx> {
    marker: PhantomData<&'ctx Context<'ctx>>,
    ptr: *mut gccjit_sys::gcc_jit_lvalue
}

/// ToLValue is a trait implemented by types that can be converted (or treated
/// as) LValues.
pub trait ToLValue<'ctx> {
    fn to_lvalue(&self) -> LValue<'ctx>;
}

impl<'ctx> ToObject<'ctx> for LValue<'ctx> {
    fn to_object(&self) -> Object<'ctx> {
        unsafe {
            object::from_ptr(gccjit_sys::gcc_jit_lvalue_as_object(self.ptr))
        }
    }
}

impl<'ctx> fmt::Debug for LValue<'ctx> {
    fn fmt<'a>(&self, fmt: &mut fmt::Formatter<'a>) -> Result<(), fmt::Error> {
        let obj = self.to_object();
        obj.fmt(fmt)
    }
}

impl<'ctx> ToLValue<'ctx> for LValue<'ctx> {
    fn to_lvalue(&self) -> LValue<'ctx> {
        unsafe { from_ptr(self.ptr) }
    }
}

impl<'ctx> ToRValue<'ctx> for LValue<'ctx> {
    fn to_rvalue(&self) -> RValue<'ctx> {
        unsafe {
            let ptr = gccjit_sys::gcc_jit_lvalue_as_rvalue(self.ptr);
            rvalue::from_ptr(ptr)
        }
    }
}

impl<'ctx> LValue<'ctx> {
    /// Given an LValue x and a Field f, gets an LValue for the field
    /// access x.f.
    pub fn access_field(&self,
                        loc: Option<Location<'ctx>>,
                        field: Field<'ctx>) -> LValue<'ctx> {
        let loc_ptr = match loc {
            Some(loc) => unsafe { location::get_ptr(&loc) },
            None => ptr::null_mut()
        };
        unsafe {
            let ptr = gccjit_sys::gcc_jit_lvalue_access_field(self.ptr,
                                                              loc_ptr,
                                                              field::get_ptr(&field));
            from_ptr(ptr)
        }
    }

    /// Given an LValue x, returns the RValue address of x, akin to C's &x.
    pub fn get_address(&self,
                       loc: Option<Location<'ctx>>) -> RValue<'ctx> {
        let loc_ptr = match loc {
            Some(loc) => unsafe { location::get_ptr(&loc) },
            None => ptr::null_mut()
        };
        unsafe {
            let ptr = gccjit_sys::gcc_jit_lvalue_get_address(self.ptr,
                                                             loc_ptr);
            rvalue::from_ptr(ptr)
        }
    }

    /// Set the initialization value for a global variable.
    pub fn global_set_initializer(&self, blob: &[u8]) {
        unsafe {
            gccjit_sys::gcc_jit_global_set_initializer(self.ptr, blob.as_ptr() as _, blob.len() as _);
        }
    }

    /// Set the initialization value for a global variable.
    pub fn global_set_initializer_rvalue(&self, value: RValue<'ctx>) -> LValue<'ctx> {
        unsafe {
            from_ptr(gccjit_sys::gcc_jit_global_set_initializer_rvalue(self.ptr, rvalue::get_ptr(&value)))
        }
    }

    #[cfg(feature="master")]
    pub fn remove(&self) {
        unsafe {
            gccjit_sys::gcc_jit_lvalue_remove(self.ptr);
        }
    }

    pub fn set_tls_model(&self, model: TlsModel) {
        unsafe {
            gccjit_sys::gcc_jit_lvalue_set_tls_model(self.ptr, model.to_sys());
        }
    }

    pub fn set_link_section(&self, name: &str) {
        let name = CString::new(name).unwrap();
        unsafe {
            gccjit_sys::gcc_jit_lvalue_set_link_section(self.ptr, name.as_ptr());
        }
    }

    #[cfg(feature="master")]
    pub fn global_set_readonly(&self) {
        unsafe {
            gccjit_sys::gcc_jit_global_set_readonly(self.ptr);
        }
    }

    pub fn set_register_name(&self, reg_name: &str) {
        let name = CString::new(reg_name).unwrap();
        unsafe {
            gccjit_sys::gcc_jit_lvalue_set_register_name(self.ptr, name.as_ptr());
        }
    }

    pub fn set_alignment(&self, alignment: i32) {
        unsafe {
            gccjit_sys::gcc_jit_lvalue_set_alignment(self.ptr, alignment);
        }
    }

    pub fn get_alignment(&self) -> i32 {
        unsafe {
            gccjit_sys::gcc_jit_lvalue_get_alignment(self.ptr)
        }
    }

    #[cfg(feature="master")]
    pub fn add_attribute(&self, attribute: VarAttribute) {
        let value = attribute.get_value();
        match value {
            AttributeValue::Int(_) => unimplemented!(),
            AttributeValue::IntArray(_) => unimplemented!(),
            AttributeValue::None => {
                unsafe {
                    gccjit_sys::gcc_jit_lvalue_add_attribute(self.ptr, attribute.to_sys());
                }
            },
            AttributeValue::String(string) => {
                let cstr = CString::new(string).unwrap();
                unsafe {
                    gccjit_sys::gcc_jit_lvalue_add_string_attribute(self.ptr, attribute.to_sys(), cstr.as_ptr());
                }
            },
        }
    }
}

pub unsafe fn from_ptr<'ctx>(ptr: *mut gccjit_sys::gcc_jit_lvalue) -> LValue<'ctx> {
    LValue {
        marker: PhantomData,
        ptr
    }
}

pub unsafe fn get_ptr<'ctx>(lvalue: &LValue<'ctx>) -> *mut gccjit_sys::gcc_jit_lvalue {
    lvalue.ptr
}
