use alloc::vec::Vec;
use indexmap::IndexSet;
use std::ops::{Deref, DerefMut};

use crate::common::{Encoding, RangeListsOffset, SectionId};
use crate::write::{Address, BaseId, Error, Result, Section, Sections, Writer};

define_section!(
    DebugRanges,
    RangeListsOffset,
    "A writable `.debug_ranges` section."
);
define_section!(
    DebugRngLists,
    RangeListsOffset,
    "A writable `.debug_rnglists` section."
);

define_offsets!(
    RangeListOffsets: RangeListId => RangeListsOffset,
    "The section offsets of a series of range lists within the `.debug_ranges` or `.debug_rnglists` sections."
);

define_id!(
    RangeListId,
    "An identifier for a range list in a `RangeListTable`."
);

/// A table of range lists that will be stored in a `.debug_ranges` or `.debug_rnglists` section.
#[derive(Debug, Default)]
pub struct RangeListTable {
    base_id: BaseId,
    ranges: IndexSet<RangeList>,
}

impl RangeListTable {
    /// Add a range list to the table.
    pub fn add(&mut self, range_list: RangeList) -> RangeListId {
        let (index, _) = self.ranges.insert_full(range_list);
        RangeListId::new(self.base_id, index)
    }

    /// Write the range list table to the appropriate section for the given DWARF version.
    pub(crate) fn write<W: Writer>(
        &self,
        sections: &mut Sections<W>,
        encoding: Encoding,
    ) -> Result<RangeListOffsets> {
        if self.ranges.is_empty() {
            return Ok(RangeListOffsets::none());
        }

        match encoding.version {
            2..=4 => self.write_ranges(&mut sections.debug_ranges, encoding.address_size),
            5 => self.write_rnglists(&mut sections.debug_rnglists, encoding),
            _ => Err(Error::UnsupportedVersion(encoding.version)),
        }
    }

    /// Write the range list table to the `.debug_ranges` section.
    fn write_ranges<W: Writer>(
        &self,
        w: &mut DebugRanges<W>,
        address_size: u8,
    ) -> Result<RangeListOffsets> {
        let mut offsets = Vec::new();
        for range_list in self.ranges.iter() {
            offsets.push(w.offset());
            for range in &range_list.0 {
                // Note that we must ensure none of the ranges have both begin == 0 and end == 0.
                // We do this by ensuring that begin != end, which is a bit more restrictive
                // than required, but still seems reasonable.
                match *range {
                    Range::BaseAddress { address } => {
                        let marker = !0 >> (64 - address_size * 8);
                        w.write_udata(marker, address_size)?;
                        w.write_address(address, address_size)?;
                    }
                    Range::OffsetPair { begin, end } => {
                        if begin == end {
                            return Err(Error::InvalidRange);
                        }
                        w.write_udata(begin, address_size)?;
                        w.write_udata(end, address_size)?;
                    }
                    Range::StartEnd { begin, end } => {
                        if begin == end {
                            return Err(Error::InvalidRange);
                        }
                        w.write_address(begin, address_size)?;
                        w.write_address(end, address_size)?;
                    }
                    Range::StartLength { begin, length } => {
                        let end = match begin {
                            Address::Constant(begin) => Address::Constant(begin + length),
                            Address::Symbol { symbol, addend } => Address::Symbol {
                                symbol,
                                addend: addend + length as i64,
                            },
                        };
                        if begin == end {
                            return Err(Error::InvalidRange);
                        }
                        w.write_address(begin, address_size)?;
                        w.write_address(end, address_size)?;
                    }
                }
            }
            w.write_udata(0, address_size)?;
            w.write_udata(0, address_size)?;
        }
        Ok(RangeListOffsets {
            base_id: self.base_id,
            offsets,
        })
    }

    /// Write the range list table to the `.debug_rnglists` section.
    fn write_rnglists<W: Writer>(
        &self,
        w: &mut DebugRngLists<W>,
        encoding: Encoding,
    ) -> Result<RangeListOffsets> {
        let mut offsets = Vec::new();

        if encoding.version != 5 {
            return Err(Error::NeedVersion(5));
        }

        let length_offset = w.write_initial_length(encoding.format)?;
        let length_base = w.len();

        w.write_u16(encoding.version)?;
        w.write_u8(encoding.address_size)?;
        w.write_u8(0)?; // segment_selector_size
        w.write_u32(0)?; // offset_entry_count (when set to zero DW_FORM_rnglistx can't be used, see section 7.28)
                         // FIXME implement DW_FORM_rnglistx writing and implement the offset entry list

        for range_list in self.ranges.iter() {
            offsets.push(w.offset());
            for range in &range_list.0 {
                match *range {
                    Range::BaseAddress { address } => {
                        w.write_u8(crate::constants::DW_RLE_base_address.0)?;
                        w.write_address(address, encoding.address_size)?;
                    }
                    Range::OffsetPair { begin, end } => {
                        w.write_u8(crate::constants::DW_RLE_offset_pair.0)?;
                        w.write_uleb128(begin)?;
                        w.write_uleb128(end)?;
                    }
                    Range::StartEnd { begin, end } => {
                        w.write_u8(crate::constants::DW_RLE_start_end.0)?;
                        w.write_address(begin, encoding.address_size)?;
                        w.write_address(end, encoding.address_size)?;
                    }
                    Range::StartLength { begin, length } => {
                        w.write_u8(crate::constants::DW_RLE_start_length.0)?;
                        w.write_address(begin, encoding.address_size)?;
                        w.write_uleb128(length)?;
                    }
                }
            }

            w.write_u8(crate::constants::DW_RLE_end_of_list.0)?;
        }

        let length = (w.len() - length_base) as u64;
        w.write_initial_length_at(length_offset, length, encoding.format)?;

        Ok(RangeListOffsets {
            base_id: self.base_id,
            offsets,
        })
    }
}

/// A range list that will be stored in a `.debug_ranges` or `.debug_rnglists` section.
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct RangeList(pub Vec<Range>);

/// A single range.
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub enum Range {
    /// DW_RLE_base_address
    BaseAddress {
        /// Base address.
        address: Address,
    },
    /// DW_RLE_offset_pair
    OffsetPair {
        /// Start of range relative to base address.
        begin: u64,
        /// End of range relative to base address.
        end: u64,
    },
    /// DW_RLE_start_end
    StartEnd {
        /// Start of range.
        begin: Address,
        /// End of range.
        end: Address,
    },
    /// DW_RLE_start_length
    StartLength {
        /// Start of range.
        begin: Address,
        /// Length of range.
        length: u64,
    },
}

#[cfg(feature = "read")]
mod convert {
    use super::*;

    use crate::read::{self, Reader};
    use crate::write::{ConvertError, ConvertResult, ConvertUnitContext};

    impl RangeList {
        /// Create a range list by reading the data from the give range list iter.
        pub(crate) fn from<R: Reader<Offset = usize>>(
            mut from: read::RawRngListIter<R>,
            context: &ConvertUnitContext<R>,
        ) -> ConvertResult<Self> {
            let mut have_base_address = context.base_address != Address::Constant(0);
            let convert_address =
                |x| (context.convert_address)(x).ok_or(ConvertError::InvalidAddress);
            let mut ranges = Vec::new();
            while let Some(from_range) = from.next()? {
                let range = match from_range {
                    read::RawRngListEntry::AddressOrOffsetPair { begin, end } => {
                        // These were parsed as addresses, even if they are offsets.
                        let begin = convert_address(begin)?;
                        let end = convert_address(end)?;
                        match (begin, end) {
                            (Address::Constant(begin_offset), Address::Constant(end_offset)) => {
                                if have_base_address {
                                    Range::OffsetPair {
                                        begin: begin_offset,
                                        end: end_offset,
                                    }
                                } else {
                                    Range::StartEnd { begin, end }
                                }
                            }
                            _ => {
                                if have_base_address {
                                    // At least one of begin/end is an address, but we also have
                                    // a base address. Adding addresses is undefined.
                                    return Err(ConvertError::InvalidRangeRelativeAddress);
                                }
                                Range::StartEnd { begin, end }
                            }
                        }
                    }
                    read::RawRngListEntry::BaseAddress { addr } => {
                        have_base_address = true;
                        let address = convert_address(addr)?;
                        Range::BaseAddress { address }
                    }
                    read::RawRngListEntry::BaseAddressx { addr } => {
                        have_base_address = true;
                        let address = convert_address(context.dwarf.address(context.unit, addr)?)?;
                        Range::BaseAddress { address }
                    }
                    read::RawRngListEntry::StartxEndx { begin, end } => {
                        let begin = convert_address(context.dwarf.address(context.unit, begin)?)?;
                        let end = convert_address(context.dwarf.address(context.unit, end)?)?;
                        Range::StartEnd { begin, end }
                    }
                    read::RawRngListEntry::StartxLength { begin, length } => {
                        let begin = convert_address(context.dwarf.address(context.unit, begin)?)?;
                        Range::StartLength { begin, length }
                    }
                    read::RawRngListEntry::OffsetPair { begin, end } => {
                        Range::OffsetPair { begin, end }
                    }
                    read::RawRngListEntry::StartEnd { begin, end } => {
                        let begin = convert_address(begin)?;
                        let end = convert_address(end)?;
                        Range::StartEnd { begin, end }
                    }
                    read::RawRngListEntry::StartLength { begin, length } => {
                        let begin = convert_address(begin)?;
                        Range::StartLength { begin, length }
                    }
                };
                // Filtering empty ranges out.
                match range {
                    Range::StartLength { length, .. } if length == 0 => continue,
                    Range::StartEnd { begin, end, .. } if begin == end => continue,
                    Range::OffsetPair { begin, end, .. } if begin == end => continue,
                    _ => (),
                }
                ranges.push(range);
            }
            Ok(RangeList(ranges))
        }
    }
}

#[cfg(test)]
#[cfg(feature = "read")]
mod tests {
    use super::*;
    use crate::common::{
        DebugAbbrevOffset, DebugAddrBase, DebugInfoOffset, DebugLocListsBase, DebugRngListsBase,
        DebugStrOffsetsBase, Format,
    };
    use crate::read;
    use crate::write::{
        ConvertUnitContext, EndianVec, LineStringTable, LocationListTable, Range, RangeListTable,
        StringTable,
    };
    use crate::LittleEndian;
    use std::collections::HashMap;
    use std::sync::Arc;

    #[test]
    fn test_range() {
        let mut line_strings = LineStringTable::default();
        let mut strings = StringTable::default();

        for &version in &[2, 3, 4, 5] {
            for &address_size in &[4, 8] {
                for &format in &[Format::Dwarf32, Format::Dwarf64] {
                    let encoding = Encoding {
                        format,
                        version,
                        address_size,
                    };

                    let mut range_list = RangeList(vec![
                        Range::StartLength {
                            begin: Address::Constant(6666),
                            length: 7777,
                        },
                        Range::StartEnd {
                            begin: Address::Constant(4444),
                            end: Address::Constant(5555),
                        },
                        Range::BaseAddress {
                            address: Address::Constant(1111),
                        },
                        Range::OffsetPair {
                            begin: 2222,
                            end: 3333,
                        },
                    ]);

                    let mut ranges = RangeListTable::default();
                    let range_list_id = ranges.add(range_list.clone());

                    let mut sections = Sections::new(EndianVec::new(LittleEndian));
                    let range_list_offsets = ranges.write(&mut sections, encoding).unwrap();

                    let read_debug_ranges =
                        read::DebugRanges::new(sections.debug_ranges.slice(), LittleEndian);
                    let read_debug_rnglists =
                        read::DebugRngLists::new(sections.debug_rnglists.slice(), LittleEndian);
                    let read_ranges = read::RangeLists::new(read_debug_ranges, read_debug_rnglists);
                    let offset = range_list_offsets.get(range_list_id);
                    let read_range_list = read_ranges.raw_ranges(offset, encoding).unwrap();

                    let dwarf = read::Dwarf {
                        ranges: read_ranges,
                        ..Default::default()
                    };
                    let unit = read::Unit {
                        header: read::UnitHeader::new(
                            encoding,
                            0,
                            read::UnitType::Compilation,
                            DebugAbbrevOffset(0),
                            DebugInfoOffset(0).into(),
                            read::EndianSlice::default(),
                        ),
                        abbreviations: Arc::new(read::Abbreviations::default()),
                        name: None,
                        comp_dir: None,
                        low_pc: 0,
                        str_offsets_base: DebugStrOffsetsBase(0),
                        addr_base: DebugAddrBase(0),
                        loclists_base: DebugLocListsBase(0),
                        rnglists_base: DebugRngListsBase(0),
                        line_program: None,
                        dwo_id: None,
                    };
                    let context = ConvertUnitContext {
                        dwarf: &dwarf,
                        unit: &unit,
                        line_strings: &mut line_strings,
                        strings: &mut strings,
                        ranges: &mut ranges,
                        locations: &mut LocationListTable::default(),
                        convert_address: &|address| Some(Address::Constant(address)),
                        base_address: Address::Constant(0),
                        line_program_offset: None,
                        line_program_files: Vec::new(),
                        entry_ids: &HashMap::new(),
                    };
                    let convert_range_list = RangeList::from(read_range_list, &context).unwrap();

                    if version <= 4 {
                        range_list.0[0] = Range::StartEnd {
                            begin: Address::Constant(6666),
                            end: Address::Constant(6666 + 7777),
                        };
                    }
                    assert_eq!(range_list, convert_range_list);
                }
            }
        }
    }
}
