use std::ops::Range;

use crate::types::{IntrinsicType, TypeKind};
use crate::Language;

/// An argument for the intrinsic.
#[derive(Debug, PartialEq, Clone)]
pub struct Argument {
    /// The argument's index in the intrinsic function call.
    pub pos: usize,
    /// The argument name.
    pub name: String,
    /// The type of the argument.
    pub ty: IntrinsicType,
    /// Any constraints that are on this argument
    pub constraints: Vec<Constraint>,
}

#[derive(Debug, PartialEq, Clone)]
pub enum Constraint {
    Equal(i64),
    Range(Range<i64>),
}

impl Constraint {
    pub fn to_range(&self) -> Range<i64> {
        match self {
            Constraint::Equal(eq) => *eq..*eq + 1,
            Constraint::Range(range) => range.clone(),
        }
    }
}

impl Argument {
    fn to_c_type(&self) -> String {
        self.ty.c_type()
    }

    fn is_simd(&self) -> bool {
        self.ty.is_simd()
    }

    pub fn is_ptr(&self) -> bool {
        self.ty.is_ptr()
    }

    pub fn has_constraint(&self) -> bool {
        !self.constraints.is_empty()
    }
}

#[derive(Debug, PartialEq, Clone)]
pub struct ArgumentList {
    pub args: Vec<Argument>,
}

impl ArgumentList {
    /// Converts the argument list into the call parameters for a C function call.
    /// e.g. this would generate something like `a, &b, c`
    pub fn as_call_param_c(&self) -> String {
        self.args
            .iter()
            .map(|arg| match arg.ty {
                IntrinsicType::Ptr { .. } => {
                    format!("&{}", arg.name)
                }
                IntrinsicType::Type { .. } => arg.name.clone(),
            })
            .collect::<Vec<String>>()
            .join(", ")
    }

    /// Converts the argument list into the call parameters for a Rust function.
    /// e.g. this would generate something like `a, b, c`
    pub fn as_call_param_rust(&self) -> String {
        self.args
            .iter()
            .filter(|a| !a.has_constraint())
            .map(|arg| arg.name.clone())
            .collect::<Vec<String>>()
            .join(", ")
    }

    pub fn as_constraint_parameters_rust(&self) -> String {
        self.args
            .iter()
            .filter(|a| a.has_constraint())
            .map(|arg| arg.name.clone())
            .collect::<Vec<String>>()
            .join(", ")
    }

    /// Creates a line for each argument that initializes an array for C from which `loads` argument
    /// values can be loaded  as a sliding window.
    /// e.g `const int32x2_t a_vals = {0x3effffff, 0x3effffff, 0x3f7fffff}`, if loads=2.
    pub fn gen_arglists_c(&self, loads: u32) -> String {
        self.iter()
            .filter_map(|arg| {
                (!arg.has_constraint()).then(|| {
                    format!(
                        "const {ty} {name}_vals[] = {{ {values} }};",
                        ty = arg.ty.c_scalar_type(),
                        name = arg.name,
                        values = arg.ty.populate_random(loads, &Language::C)
                    )
                })
            })
            .collect::<Vec<_>>()
            .join("\n")
    }

    /// Creates a line for each argument that initializes an array for Rust from which `loads` argument
    /// values can be loaded as a sliding window, e.g `const A_VALS: [u32; 20]  = [...];`
    pub fn gen_arglists_rust(&self, loads: u32) -> String {
        self.iter()
            .filter_map(|arg| {
                (!arg.has_constraint()).then(|| {
                    format!(
                        "const {upper_name}_VALS: [{ty}; {load_size}] = unsafe{{ [{values}] }};",
                        upper_name = arg.name.to_uppercase(),
                        ty = arg.ty.rust_scalar_type(),
                        load_size = arg.ty.num_lanes() * arg.ty.num_vectors() + loads - 1,
                        values = arg.ty.populate_random(loads, &Language::Rust)
                    )
                })
            })
            .collect::<Vec<_>>()
            .join("\n")
    }

    /// Creates a line for each argument that initalizes the argument from an array [arg]_vals at
    /// an offset i using a load intrinsic, in C.
    /// e.g `uint8x8_t a = vld1_u8(&a_vals[i]);`
    pub fn load_values_c(&self, p64_armv7_workaround: bool) -> String {
        self.iter()
            .filter_map(|arg| {
                // The ACLE doesn't support 64-bit polynomial loads on Armv7
                // This and the cast are a workaround for this
                let armv7_p64 = if let TypeKind::Poly = arg.ty.kind() {
                    p64_armv7_workaround
                } else {
                    false
                };

                (!arg.has_constraint()).then(|| {
                    format!(
                        "{ty} {name} = {open_cast}{load}(&{name}_vals[i]){close_cast};",
                        ty = arg.to_c_type(),
                        name = arg.name,
                        load = if arg.is_simd() {
                            arg.ty.get_load_function(p64_armv7_workaround)
                        } else {
                            "*".to_string()
                        },
                        open_cast = if armv7_p64 {
                            format!("cast<{}>(", arg.to_c_type())
                        } else {
                            "".to_string()
                        },
                        close_cast = if armv7_p64 {
                            ")".to_string()
                        } else {
                            "".to_string()
                        }
                    )
                })
            })
            .collect::<Vec<_>>()
            .join("\n        ")
    }

    /// Creates a line for each argument that initalizes the argument from array [ARG]_VALS at
    /// an offset i using a load intrinsic, in Rust.
    /// e.g `let a = vld1_u8(A_VALS.as_ptr().offset(i));`
    pub fn load_values_rust(&self) -> String {
        self.iter()
            .filter_map(|arg| {
                (!arg.has_constraint()).then(|| {
                    format!(
                        "let {name} = {load}({upper_name}_VALS.as_ptr().offset(i));",
                        name = arg.name,
                        upper_name = arg.name.to_uppercase(),
                        load = if arg.is_simd() {
                            arg.ty.get_load_function(false)
                        } else {
                            "*".to_string()
                        },
                    )
                })
            })
            .collect::<Vec<_>>()
            .join("\n            ")
    }

    pub fn iter(&self) -> std::slice::Iter<'_, Argument> {
        self.args.iter()
    }
}
