use crate::error;
use alloc::string::ToString;
use alloc::vec::Vec;
use scroll::Pread;

use super::options;
use super::section_table;

use crate::pe::data_directories::DataDirectory;
use core::cmp;

use log::debug;

pub fn is_in_range(rva: usize, r1: usize, r2: usize) -> bool {
    r1 <= rva && rva < r2
}

// reference: Peter Ferrie. Reliable algorithm to extract overlay of a PE. https://bit.ly/2vBX2bR
#[inline]
fn aligned_pointer_to_raw_data(pointer_to_raw_data: usize) -> usize {
    const PHYSICAL_ALIGN: usize = 0x1ff;
    pointer_to_raw_data & !PHYSICAL_ALIGN
}

#[inline]
fn section_read_size(section: &section_table::SectionTable, file_alignment: u32) -> usize {
    fn round_size(size: usize) -> usize {
        const PAGE_MASK: usize = 0xfff;
        (size + PAGE_MASK) & !PAGE_MASK
    }

    // Paraphrased from https://reverseengineering.stackexchange.com/a/4326 (by Peter Ferrie).
    //
    // Handles the corner cases such as mis-aligned pointers (round down) and sizes (round up)
    // Further rounding corner cases:
    // - the physical pointer should be rounded down to a multiple of 512, regardless of the value in the header
    // - the read size is rounded up by using a combination of the file alignment and 4kb
    // - the virtual size is always rounded up to a multiple of 4kb, regardless of the value in the header.
    //
    // Reference C implementation:
    //
    // long pointerToRaw = section.get(POINTER_TO_RAW_DATA);
    // long alignedpointerToRaw = pointerToRaw & ~0x1ff;
    // long sizeOfRaw = section.get(SIZE_OF_RAW_DATA);
    // long readsize = ((pointerToRaw + sizeOfRaw) + filealign - 1) & ~(filealign - 1)) - alignedpointerToRaw;
    // readsize = min(readsize, (sizeOfRaw + 0xfff) & ~0xfff);
    // long virtsize = section.get(VIRTUAL_SIZE);
    //
    // if (virtsize)
    // {
    //     readsize = min(readsize, (virtsize + 0xfff) & ~0xfff);
    // }

    let file_alignment = file_alignment as usize;
    let size_of_raw_data = section.size_of_raw_data as usize;
    let virtual_size = section.virtual_size as usize;
    let read_size = {
        let read_size =
            ((section.pointer_to_raw_data as usize + size_of_raw_data + file_alignment - 1)
                & !(file_alignment - 1))
                - aligned_pointer_to_raw_data(section.pointer_to_raw_data as usize);
        cmp::min(read_size, round_size(size_of_raw_data))
    };

    if virtual_size == 0 {
        read_size
    } else {
        cmp::min(read_size, round_size(virtual_size))
    }
}

fn rva2offset(rva: usize, section: &section_table::SectionTable) -> usize {
    (rva - section.virtual_address as usize)
        + aligned_pointer_to_raw_data(section.pointer_to_raw_data as usize)
}

fn is_in_section(rva: usize, section: &section_table::SectionTable, file_alignment: u32) -> bool {
    let section_rva = section.virtual_address as usize;
    is_in_range(
        rva,
        section_rva,
        section_rva + section_read_size(section, file_alignment),
    )
}

pub fn find_offset(
    rva: usize,
    sections: &[section_table::SectionTable],
    file_alignment: u32,
    opts: &options::ParseOptions,
) -> Option<usize> {
    if opts.resolve_rva {
        if file_alignment == 0 || file_alignment & (file_alignment - 1) != 0 {
            return None;
        }
        for (i, section) in sections.iter().enumerate() {
            debug!(
                "Checking {} for {:#x} ∈ {:#x}..{:#x}",
                section.name().unwrap_or(""),
                rva,
                section.virtual_address,
                section.virtual_address + section.virtual_size
            );
            if is_in_section(rva, &section, file_alignment) {
                let offset = rva2offset(rva, &section);
                debug!(
                    "Found in section {}({}), remapped into offset {:#x}",
                    section.name().unwrap_or(""),
                    i,
                    offset
                );
                return Some(offset);
            }
        }
        None
    } else {
        Some(rva)
    }
}

pub fn find_offset_or(
    rva: usize,
    sections: &[section_table::SectionTable],
    file_alignment: u32,
    opts: &options::ParseOptions,
    msg: &str,
) -> error::Result<usize> {
    find_offset(rva, sections, file_alignment, opts)
        .ok_or_else(|| error::Error::Malformed(msg.to_string()))
}

pub fn try_name<'a>(
    bytes: &'a [u8],
    rva: usize,
    sections: &[section_table::SectionTable],
    file_alignment: u32,
    opts: &options::ParseOptions,
) -> error::Result<&'a str> {
    match find_offset(rva, sections, file_alignment, opts) {
        Some(offset) => Ok(bytes.pread::<&str>(offset)?),
        None => Err(error::Error::Malformed(format!(
            "Cannot find name from rva {:#x} in sections: {:?}",
            rva, sections
        ))),
    }
}

pub fn get_data<'a, T>(
    bytes: &'a [u8],
    sections: &[section_table::SectionTable],
    directory: DataDirectory,
    file_alignment: u32,
) -> error::Result<T>
where
    T: scroll::ctx::TryFromCtx<'a, scroll::Endian, Error = scroll::Error>,
{
    get_data_with_opts(
        bytes,
        sections,
        directory,
        file_alignment,
        &options::ParseOptions::default(),
    )
}

pub fn get_data_with_opts<'a, T>(
    bytes: &'a [u8],
    sections: &[section_table::SectionTable],
    directory: DataDirectory,
    file_alignment: u32,
    opts: &options::ParseOptions,
) -> error::Result<T>
where
    T: scroll::ctx::TryFromCtx<'a, scroll::Endian, Error = scroll::Error>,
{
    let rva = directory.virtual_address as usize;
    let offset = find_offset(rva, sections, file_alignment, opts)
        .ok_or_else(|| error::Error::Malformed(directory.virtual_address.to_string()))?;
    let result: T = bytes.pread_with(offset, scroll::LE)?;
    Ok(result)
}

pub(crate) fn pad(length: usize, alignment: Option<usize>) -> Option<Vec<u8>> {
    match alignment {
        Some(alignment) => {
            let overhang = length % alignment;
            if overhang != 0 {
                let repeat = alignment - overhang;
                Some(vec![0u8; repeat])
            } else {
                None
            }
        }
        None => None,
    }
}
