/*
 * This file is part of the flashrom project.
 *
 * Copyright (C) 2022 The Chromium OS Authors
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

//! # libflashrom
//!
//! The `libflashrom` library is a rust FFI binding to the flashrom library.
//! libflashrom can be used to read write and modify some settings of flash chips.
//! The library closely follows the libflashrom C API, but exports a `safe` interface
//! including automatic resource management and forced error checking.
//!
//! libflashrom does not support threading, all usage of this library must occur on one thread.
//!
//! Most of the library functionality is defined on the [`Chip`] type.
//!
//! Example:
//!
//! ```
//! use libflashrom::*;
//! let mut chip = Chip::new(
//!     Programmer::new("dummy", Some("emulate=W25Q128FV")).unwrap(),
//!     Some("W25Q128.V")
//! ).unwrap();
//! let mut buf = chip.image_read(None).unwrap();
//! buf[0] = 0xFE;
//! chip.image_write(&mut buf, None).unwrap();
//! ```

use once_cell::sync::Lazy;
use regex::Regex;
use std::error;
use std::ffi::c_void;
use std::ffi::CStr;
use std::ffi::CString;
use std::fmt;
use std::io::Write;
use std::ptr::null;
use std::ptr::null_mut;
use std::ptr::NonNull;
use std::sync::Mutex;
use std::sync::Once;

pub use libflashrom_sys::{
    flashrom_log_level, FLASHROM_MSG_DEBUG, FLASHROM_MSG_DEBUG2, FLASHROM_MSG_ERROR,
    FLASHROM_MSG_INFO, FLASHROM_MSG_SPEW, FLASHROM_MSG_WARN,
};

pub use libflashrom_sys::flashrom_wp_mode;

// libflashrom uses (start, len) or inclusive [start, end] for ranges.
// This type exists to rust RangeBounds types to a convenient internal format.
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
struct RangeInternal {
    start: usize,
    len: usize,
}

/// The type returned for write protect and layout queries
pub type Range = std::ops::Range<usize>;

impl<T> From<T> for RangeInternal
where
    T: std::ops::RangeBounds<usize>,
{
    fn from(range: T) -> Self {
        let start = match range.start_bound() {
            std::ops::Bound::Included(start) => *start,
            std::ops::Bound::Excluded(start) => *start + 1,
            std::ops::Bound::Unbounded => 0,
        };
        RangeInternal {
            start,
            len: match range.end_bound() {
                std::ops::Bound::Included(end) => *end - start + 1,
                std::ops::Bound::Excluded(end) => *end - start,
                std::ops::Bound::Unbounded => usize::MAX - start,
            },
        }
    }
}

impl RangeInternal {
    // inclusive end for libflashrom
    fn end(&self) -> usize {
        self.start + self.len - 1
    }
}

// log_c is set to be the callback at [`Programmer`] init. It deals with va_list and calls log_rust.
// log_rust calls a user defined function, or by default log_eprint.
// log_eprint just writes to stderr.
extern "C" {
    fn set_log_callback();
    // Modifying and reading current_level is not thread safe, but neither is
    // the libflashrom implementation, so we shouldnt be using threads anyway.
    static mut current_level: libflashrom_sys::flashrom_log_level;
}

/// Callers can use this function to log to the [`Logger`] they have set via [`set_log_level`]
///
/// However from rust it is likely easier to call the [`Logger`] directly.
#[no_mangle]
pub extern "C" fn log_rust(
    level: libflashrom_sys::flashrom_log_level,
    format: &std::os::raw::c_char,
) {
    // Because this function is called from C, it must not panic.
    // SAFETY: log_c always provides a non null ptr to a null terminated string
    // msg does not outlive format.
    let msg = unsafe { CStr::from_ptr(format) }.to_string_lossy();
    // Locking can fail if a thread panics while holding the lock.
    match LOG_FN.lock() {
        Ok(g) => (*g)(level, msg.as_ref()),
        Err(_) => eprintln!("ERROR: libflashrom log failure to lock function"),
    };
}

fn log_eprint(_level: libflashrom_sys::flashrom_log_level, msg: &str) {
    // Because this function is called from C, it must not panic.
    // Ignore the error.
    let _ = std::io::stderr().write_all(msg.as_bytes());
}

// Can't directly atexit(flashrom_shutdown) because it is unsafe
extern "C" fn shutdown_wrapper() {
    unsafe {
        libflashrom_sys::flashrom_shutdown();
    }
}

/// A callback to log flashrom messages. This must not panic.
pub type Logger = fn(libflashrom_sys::flashrom_log_level, &str);

static LOG_FN: Lazy<Mutex<Logger>> = Lazy::new(|| Mutex::new(log_eprint));

/// Set the maximum log message level that will be passed to [`Logger`]
///
/// log_rust and therefore the provided [`Logger`] will only be called for messages
/// greater or equal to the provided priority.
///
/// ```
/// use libflashrom::set_log_level;
/// use libflashrom::FLASHROM_MSG_SPEW;
/// // Disable logging.
/// set_log_level(None);
/// // Log all messages  at priority FLASHROM_MSG_SPEW and above.
/// set_log_level(Some(FLASHROM_MSG_SPEW));
/// ```
pub fn set_log_level(level: Option<libflashrom_sys::flashrom_log_level>) {
    // SAFETY: current_level is only read by log_c, in this thread.
    match level {
        Some(level) => unsafe { current_level = level + 1 },
        None => unsafe { current_level = 0 },
    };
}

/// Set a [`Logger`] logging callback function
///
/// Provided function must not panic, as it is called from C.
pub fn set_log_function(logger: Logger) {
    *LOG_FN.lock().unwrap() = logger;
}

/// A type holding the error code returned by libflashrom and the function that returned the error.
///
/// The error codes returned from each function differ in meaning, see libflashrom.h
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct ErrorCode {
    function: &'static str,
    code: i32,
}

impl fmt::Display for ErrorCode {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "libflashrom: {} returned {}", self.function, self.code)
    }
}

impl error::Error for ErrorCode {}

impl From<ErrorCode> for String {
    fn from(e: ErrorCode) -> Self {
        format!("{}", e)
    }
}

/// Errors from initialising libflashrom or a [`Programmer`]
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum InitError {
    DuplicateInit,
    FlashromInit(ErrorCode),
    InvalidName(std::ffi::NulError),
    ProgrammerInit(ErrorCode),
}

impl fmt::Display for InitError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:?}", self)
    }
}

impl error::Error for InitError {}

impl From<InitError> for String {
    fn from(e: InitError) -> Self {
        format!("{:?}", e)
    }
}

impl From<std::ffi::NulError> for InitError {
    fn from(err: std::ffi::NulError) -> InitError {
        InitError::InvalidName(err)
    }
}

/// Errors from probing a [`Chip`]
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum ChipInitError {
    InvalidName(std::ffi::NulError),
    NoChipError,
    MultipleChipsError,
    ProbeError,
}

impl fmt::Display for ChipInitError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:?}", self)
    }
}

impl error::Error for ChipInitError {}

impl From<ChipInitError> for String {
    fn from(e: ChipInitError) -> Self {
        format!("{:?}", e)
    }
}

impl From<std::ffi::NulError> for ChipInitError {
    fn from(err: std::ffi::NulError) -> ChipInitError {
        ChipInitError::InvalidName(err)
    }
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub enum RegionError {
    ErrorCode(ErrorCode),
    InvalidName(std::ffi::NulError),
}

impl fmt::Display for RegionError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:?}", self)
    }
}

impl error::Error for RegionError {}

impl From<RegionError> for String {
    fn from(e: RegionError) -> Self {
        format!("{:?}", e)
    }
}

impl From<std::ffi::NulError> for RegionError {
    fn from(err: std::ffi::NulError) -> RegionError {
        RegionError::InvalidName(err)
    }
}

#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct ParseLayoutError(String);

impl fmt::Display for ParseLayoutError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:?}", self)
    }
}

impl error::Error for ParseLayoutError {}

impl From<ParseLayoutError> for String {
    fn from(e: ParseLayoutError) -> Self {
        format!("{:?}", e)
    }
}

/// A translation of the flashrom_wp_result type
///
/// WpOK is omitted, as it is not an error.
/// WpErrUnknown is used for an unknown error type.
/// Keep this list in sync with libflashrom.h
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub enum WPError {
    WpErrChipUnsupported,
    WpErrOther,
    WpErrReadFailed,
    WpErrWriteFailed,
    WpErrVerifyFailed,
    WpErrRangeUnsupported,
    WpErrModeUnsupported,
    WpErrRangeListUnavailable,
    WpErrUnsupportedState,
    WpErrUnknown(libflashrom_sys::flashrom_wp_result),
}

impl From<libflashrom_sys::flashrom_wp_result> for WPError {
    fn from(e: libflashrom_sys::flashrom_wp_result) -> Self {
        assert!(e != libflashrom_sys::flashrom_wp_result::FLASHROM_WP_OK);
        match e {
            libflashrom_sys::flashrom_wp_result::FLASHROM_WP_ERR_CHIP_UNSUPPORTED => {
                WPError::WpErrChipUnsupported
            }
            libflashrom_sys::flashrom_wp_result::FLASHROM_WP_ERR_OTHER => WPError::WpErrOther,
            libflashrom_sys::flashrom_wp_result::FLASHROM_WP_ERR_READ_FAILED => {
                WPError::WpErrReadFailed
            }
            libflashrom_sys::flashrom_wp_result::FLASHROM_WP_ERR_WRITE_FAILED => {
                WPError::WpErrWriteFailed
            }
            libflashrom_sys::flashrom_wp_result::FLASHROM_WP_ERR_VERIFY_FAILED => {
                WPError::WpErrVerifyFailed
            }
            libflashrom_sys::flashrom_wp_result::FLASHROM_WP_ERR_RANGE_UNSUPPORTED => {
                WPError::WpErrRangeUnsupported
            }
            libflashrom_sys::flashrom_wp_result::FLASHROM_WP_ERR_MODE_UNSUPPORTED => {
                WPError::WpErrModeUnsupported
            }
            libflashrom_sys::flashrom_wp_result::FLASHROM_WP_ERR_RANGE_LIST_UNAVAILABLE => {
                WPError::WpErrRangeListUnavailable
            }
            libflashrom_sys::flashrom_wp_result::FLASHROM_WP_ERR_UNSUPPORTED_STATE => {
                WPError::WpErrUnsupportedState
            }
            _ => WPError::WpErrUnknown(e), // this could also be a panic
        }
    }
}

impl fmt::Display for WPError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:?}", self)
    }
}

impl error::Error for WPError {}

impl From<WPError> for String {
    fn from(e: WPError) -> Self {
        format!("{:?}", e)
    }
}

/// Return a rust sanitised string derived from flashrom_version_info.
pub fn flashrom_version_info() -> Option<String> {
    let p = unsafe { libflashrom_sys::flashrom_version_info() };
    if p.is_null() {
        None
    } else {
        // SAFETY: flashrom_version_info returns a global `const char flashrom_version[]`
        // derived from `-DFLASHROM_VERSION`, this is not guaranteed to be
        // null terminated, but is in a normal build.
        Some(unsafe { CStr::from_ptr(p) }.to_string_lossy().into_owned())
    }
}

/// Structure for an initialised flashrom_programmer
// flashrom_programmer_init returns a pointer accepted by flashrom_flash_probe
// but this is not implemented at time of writing. When implemented the pointer
// can be stored here.
#[derive(Debug)]
pub struct Programmer {}

/// Structure for an initialised flashrom chip, or flashrom_flashctx
// As returned by flashrom_flash_probe
// The layout is owned here as the chip only stores a pointer when a layout is set.
#[derive(Debug)]
pub struct Chip {
    ctx: NonNull<libflashrom_sys::flashrom_flashctx>,
    _programmer: Programmer,
    layout: Option<Layout>,
}

impl Programmer {
    /// Initialise libflashrom and a programmer
    ///
    /// See libflashrom.h flashrom_programmer_init for argument documentation.
    ///
    /// Panics:
    ///
    /// If this libflashrom implementation returns a programmer pointer.
    pub fn new(
        programmer_name: &str,
        programmer_options: Option<&str>,
    ) -> Result<Programmer, InitError> {
        static ONCE: Once = Once::new();
        if ONCE.is_completed() {
            // Flashrom does not currently support concurrent programmers
            // Flashrom also does not currently support initialising a second programmer after a first has been initialised.
            // This is used to warn the user if they try to initialise a second programmer.
            return Err(InitError::DuplicateInit);
        }
        ONCE.call_once(|| {});

        static INIT_RES: Lazy<Result<(), InitError>> = Lazy::new(|| {
            unsafe { set_log_callback() };
            // always perform_selfcheck
            let res = unsafe { libflashrom_sys::flashrom_init(1) };
            if res == 0 {
                let res = unsafe { libc::atexit(shutdown_wrapper) };
                if res == 0 {
                    Ok(())
                } else {
                    unsafe { libflashrom_sys::flashrom_shutdown() };
                    Err(InitError::FlashromInit(ErrorCode {
                        function: "atexit",
                        code: res,
                    }))
                }
            } else {
                Err(InitError::FlashromInit(ErrorCode {
                    function: "flashrom_init",
                    code: res,
                }))
            }
        });
        (*INIT_RES).clone()?;

        let mut programmer: *mut libflashrom_sys::flashrom_programmer = null_mut();
        let programmer_name = CString::new(programmer_name)?;
        let programmer_options = match programmer_options {
            Some(programmer_options) => Some(CString::new(programmer_options)?),
            None => None,
        };
        let res = unsafe {
            libflashrom_sys::flashrom_programmer_init(
                &mut programmer,
                programmer_name.as_ptr(),
                programmer_options.as_ref().map_or(null(), |x| x.as_ptr()),
            )
        };
        if res != 0 {
            Err(InitError::ProgrammerInit(ErrorCode {
                function: "flashrom_programmer_init",
                code: res,
            }))
        } else if !programmer.is_null() {
            panic!("flashrom_programmer_init returning a programmer pointer is not supported")
        } else {
            Ok(Programmer {})
        }
    }
}

impl Drop for Programmer {
    fn drop(&mut self) {
        unsafe {
            libflashrom_sys::flashrom_programmer_shutdown(null_mut());
        }
    }
}

/// A translation of the flashrom_flag type
///
/// Keep this list in sync with libflashrom.h
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub enum FlashromFlag {
    FlashromFlagForce,
    FlashromFlagForceBoardmismatch,
    FlashromFlagVerifyAfterWrite,
    FlashromFlagVerifyWholeChip,
    FlashromFlagSkipUnreadableRegions,
    FlashromFlagSkipUnwritableRegions,
}

impl From<FlashromFlag> for libflashrom_sys::flashrom_flag {
    fn from(e: FlashromFlag) -> Self {
        match e {
            FlashromFlag::FlashromFlagForce => libflashrom_sys::flashrom_flag::FLASHROM_FLAG_FORCE,
            FlashromFlag::FlashromFlagForceBoardmismatch => {
                libflashrom_sys::flashrom_flag::FLASHROM_FLAG_FORCE_BOARDMISMATCH
            }
            FlashromFlag::FlashromFlagVerifyAfterWrite => {
                libflashrom_sys::flashrom_flag::FLASHROM_FLAG_VERIFY_AFTER_WRITE
            }
            FlashromFlag::FlashromFlagVerifyWholeChip => {
                libflashrom_sys::flashrom_flag::FLASHROM_FLAG_VERIFY_WHOLE_CHIP
            }
            FlashromFlag::FlashromFlagSkipUnreadableRegions => {
                libflashrom_sys::flashrom_flag::FLASHROM_FLAG_SKIP_UNREADABLE_REGIONS
            }
            FlashromFlag::FlashromFlagSkipUnwritableRegions => {
                libflashrom_sys::flashrom_flag::FLASHROM_FLAG_SKIP_UNWRITABLE_REGIONS
            }
        }
    }
}

/// Various flags of the flashrom context
///
/// Keep the struct in sync with the flags in flash.h
#[derive(Debug)]
pub struct FlashromFlags {
    pub force: bool,
    pub force_boardmismatch: bool,
    pub verify_after_write: bool,
    pub verify_whole_chip: bool,
    pub skip_unreadable_regions: bool,
    pub skip_unwritable_regions: bool,
}

/// Keep the default values in sync with cli_classic.c
impl Default for FlashromFlags {
    fn default() -> Self {
        Self {
            force: false,
            force_boardmismatch: false,
            verify_after_write: true,
            verify_whole_chip: true,
            // These flags are introduced to address issues related to CSME locking parts. Setting
            // them to true as default values
            skip_unreadable_regions: true,
            skip_unwritable_regions: true,
        }
    }
}

impl fmt::Display for FlashromFlags {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(
            f,
            "FlashromFlags {{ force: {}, force_boardmismatch: {}, verify_after_write: {}, verify_whole_chip: {}, skip_unreadable_regions: {}, skip_unwritable_regions: {} }}",
            self.force,
            self.force_boardmismatch,
            self.verify_after_write,
            self.verify_whole_chip,
            self.skip_unreadable_regions,
            self.skip_unwritable_regions,
        )
    }
}

impl Chip {
    /// Probe for a chip
    ///
    /// See libflashrom.h flashrom_flash_probe for argument documentation.
    pub fn new(programmer: Programmer, chip_name: Option<&str>) -> Result<Chip, ChipInitError> {
        let mut flash_ctx: *mut libflashrom_sys::flashrom_flashctx = null_mut();
        let chip_name = match chip_name {
            Some(chip_name) => Some(CString::new(chip_name)?),
            None => None,
        };
        match unsafe {
            libflashrom_sys::flashrom_flash_probe(
                &mut flash_ctx,
                null(),
                chip_name.as_ref().map_or(null(), |x| x.as_ptr()),
            )
        } {
            0 => Ok(Chip {
                ctx: NonNull::new(flash_ctx).expect("flashrom_flash_probe returned null"),
                _programmer: programmer,
                layout: None,
            }),
            3 => Err(ChipInitError::MultipleChipsError),
            2 => Err(ChipInitError::NoChipError),
            _ => Err(ChipInitError::ProbeError),
        }
    }

    pub fn get_size(&self) -> usize {
        unsafe { libflashrom_sys::flashrom_flash_getsize(self.ctx.as_ref()) }
    }

    /// Read the write protect config of this [`Chip`]
    pub fn get_wp(&mut self) -> std::result::Result<WriteProtectCfg, WPError> {
        let mut cfg = WriteProtectCfg::new()?;
        let res =
            unsafe { libflashrom_sys::flashrom_wp_read_cfg(cfg.wp.as_mut(), self.ctx.as_mut()) };
        if res != libflashrom_sys::flashrom_wp_result::FLASHROM_WP_OK {
            return Err(res.into());
        }
        Ok(cfg)
    }

    /// Set the write protect config of this [`Chip`]
    pub fn set_wp(&mut self, wp: &WriteProtectCfg) -> std::result::Result<(), WPError> {
        let res =
            unsafe { libflashrom_sys::flashrom_wp_write_cfg(self.ctx.as_mut(), wp.wp.as_ref()) };
        if res != libflashrom_sys::flashrom_wp_result::FLASHROM_WP_OK {
            return Err(res.into());
        }
        Ok(())
    }

    /// Read the write protect ranges of this [`Chip`]
    ///
    /// # Panics
    ///
    /// Panics if flashrom_wp_get_available_ranges returns FLASHROM_WP_OK and a NULL pointer.
    pub fn get_wp_ranges(&mut self) -> std::result::Result<Vec<Range>, WPError> {
        let mut ranges: *mut libflashrom_sys::flashrom_wp_ranges = null_mut();
        let res = unsafe {
            libflashrom_sys::flashrom_wp_get_available_ranges(&mut ranges, self.ctx.as_mut())
        };
        if res != libflashrom_sys::flashrom_wp_result::FLASHROM_WP_OK {
            return Err(res.into());
        }
        let ranges = WriteProtectRanges {
            ranges: NonNull::new(ranges).expect("flashrom_wp_get_available_ranges returned null"),
        };

        let count =
            unsafe { libflashrom_sys::flashrom_wp_ranges_get_count(ranges.ranges.as_ref()) };
        let mut ret = Vec::with_capacity(count);
        for index in 0..count {
            let mut start = 0;
            let mut len = 0;
            let res = unsafe {
                libflashrom_sys::flashrom_wp_ranges_get_range(
                    &mut start,
                    &mut len,
                    ranges.ranges.as_ref(),
                    // TODO: fix after https://review.coreboot.org/c/flashrom/+/64996
                    index
                        .try_into()
                        .expect("flashrom_wp_ranges_get_count does not fit in a u32"),
                )
            };
            if res != libflashrom_sys::flashrom_wp_result::FLASHROM_WP_OK {
                return Err(res.into());
            }
            ret.push(start..(start + len))
        }
        Ok(ret)
    }

    /// Returns the layout read from the fmap of this [`Chip`]
    ///
    /// # Panics
    ///
    /// Panics if flashrom_layout_read_fmap_from_rom returns FLASHROM_WP_OK and a NULL pointer.
    pub fn layout_read_fmap_from_rom(&mut self) -> std::result::Result<Layout, ErrorCode> {
        let mut layout: *mut libflashrom_sys::flashrom_layout = null_mut();
        let err = unsafe {
            libflashrom_sys::flashrom_layout_read_fmap_from_rom(
                &mut layout,
                self.ctx.as_mut(),
                0,
                self.get_size(),
            )
        };
        if err != 0 {
            return Err(ErrorCode {
                function: "flashrom_layout_read_fmap_from_rom",
                code: err,
            });
        }
        Ok(Layout {
            layout: NonNull::new(layout).expect("flashrom_layout_read_fmap_from_rom returned null"),
        })
    }

    /// Sets the layout of this [`Chip`]
    ///
    /// [`Chip`] takes ownership of Layout to ensure it is not released before the [`Chip`].
    fn set_layout(&mut self, layout: Layout) {
        unsafe { libflashrom_sys::flashrom_layout_set(self.ctx.as_mut(), layout.layout.as_ref()) };
        self.layout = Some(layout)
    }

    fn unset_layout(&mut self) -> Option<Layout> {
        unsafe { libflashrom_sys::flashrom_layout_set(self.ctx.as_mut(), null()) };
        self.layout.take()
    }

    /// Read the whole [`Chip`], or a portion specified in a Layout
    pub fn image_read(
        &mut self,
        layout: Option<Layout>,
    ) -> std::result::Result<Vec<u8>, ErrorCode> {
        if let Some(layout) = layout {
            self.set_layout(layout);
        }
        let len = self.get_size();
        let mut buf = vec![0; len];
        let res = unsafe {
            libflashrom_sys::flashrom_image_read(
                self.ctx.as_mut(),
                buf.as_mut_ptr() as *mut c_void,
                len,
            )
        };
        self.unset_layout();

        if res == 0 {
            Ok(buf)
        } else {
            Err(ErrorCode {
                function: "flashrom_image_read",
                code: res,
            })
        }
    }

    /// Write the whole [`Chip`], or a portion specified in a Layout
    pub fn image_write(
        &mut self,
        buf: &mut [u8],
        layout: Option<Layout>,
    ) -> std::result::Result<(), ErrorCode> {
        if let Some(layout) = layout {
            self.set_layout(layout);
        }
        let res = unsafe {
            libflashrom_sys::flashrom_image_write(
                self.ctx.as_mut(),
                buf.as_mut_ptr() as *mut c_void,
                buf.len(),
                null(),
            )
        };
        self.unset_layout();

        if res == 0 {
            Ok(())
        } else {
            Err(ErrorCode {
                function: "flashrom_image_write",
                code: res,
            })
        }
    }

    /// Verify the whole [`Chip`], or a portion specified in a Layout
    pub fn image_verify(
        &mut self,
        buf: &[u8],
        layout: Option<Layout>,
    ) -> std::result::Result<(), ErrorCode> {
        if let Some(layout) = layout {
            self.set_layout(layout);
        }
        let res = unsafe {
            libflashrom_sys::flashrom_image_verify(
                self.ctx.as_mut(),
                buf.as_ptr() as *const c_void,
                buf.len(),
            )
        };
        self.unset_layout();

        if res == 0 {
            Ok(())
        } else {
            Err(ErrorCode {
                function: "flashrom_image_verify",
                code: res,
            })
        }
    }

    /// Erase the whole [`Chip`]
    pub fn erase(&mut self) -> std::result::Result<(), ErrorCode> {
        let res = unsafe { libflashrom_sys::flashrom_flash_erase(self.ctx.as_mut()) };
        if res == 0 {
            Ok(())
        } else {
            Err(ErrorCode {
                function: "flashrom_flash_erase",
                code: res,
            })
        }
    }

    /// Set a flag in the given flash context
    pub fn flag_set(&mut self, flag: FlashromFlag, value: bool) -> () {
        unsafe { libflashrom_sys::flashrom_flag_set(self.ctx.as_mut(), flag.into(), value) }
    }
}

impl Drop for Chip {
    fn drop(&mut self) {
        unsafe {
            libflashrom_sys::flashrom_flash_release(self.ctx.as_mut());
        }
    }
}

/// Structure for an initialised flashrom_wp_cfg
#[derive(Debug)]
pub struct WriteProtectCfg {
    wp: NonNull<libflashrom_sys::flashrom_wp_cfg>,
}

impl WriteProtectCfg {
    /// Create an empty [`WriteProtectCfg`]
    ///
    /// # Panics
    ///
    /// Panics if flashrom_wp_cfg_new returns FLASHROM_WP_OK and a NULL pointer.
    pub fn new() -> std::result::Result<WriteProtectCfg, WPError> {
        let mut cfg: *mut libflashrom_sys::flashrom_wp_cfg = null_mut();
        let res = unsafe { libflashrom_sys::flashrom_wp_cfg_new(&mut cfg) };
        if res != libflashrom_sys::flashrom_wp_result::FLASHROM_WP_OK {
            return Err(res.into());
        }
        Ok(WriteProtectCfg {
            wp: NonNull::new(cfg).expect("flashrom_wp_cfg_new returned null"),
        })
    }

    pub fn get_mode(&self) -> libflashrom_sys::flashrom_wp_mode {
        unsafe { libflashrom_sys::flashrom_wp_get_mode(self.wp.as_ref()) }
    }

    pub fn set_mode(&mut self, mode: libflashrom_sys::flashrom_wp_mode) {
        unsafe { libflashrom_sys::flashrom_wp_set_mode(self.wp.as_mut(), mode) }
    }

    pub fn get_range(&self) -> Range {
        let mut start = 0;
        let mut len = 0;
        unsafe { libflashrom_sys::flashrom_wp_get_range(&mut start, &mut len, self.wp.as_ref()) };
        start..(start + len)
    }

    pub fn set_range<T>(&mut self, range: T)
    where
        T: std::ops::RangeBounds<usize>,
    {
        let range: RangeInternal = range.into();
        unsafe { libflashrom_sys::flashrom_wp_set_range(self.wp.as_mut(), range.start, range.len) }
    }
}

impl Drop for WriteProtectCfg {
    fn drop(&mut self) {
        unsafe {
            libflashrom_sys::flashrom_wp_cfg_release(self.wp.as_mut());
        }
    }
}

impl fmt::Display for WriteProtectCfg {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "range:{:?} mode:{:?}", self.get_range(), self.get_mode())
    }
}

#[derive(Debug)]
struct WriteProtectRanges {
    ranges: NonNull<libflashrom_sys::flashrom_wp_ranges>,
}

impl WriteProtectRanges {}

impl Drop for WriteProtectRanges {
    fn drop(&mut self) {
        unsafe {
            libflashrom_sys::flashrom_wp_ranges_release(self.ranges.as_mut());
        }
    }
}

/// Structure for an initialised flashrom_layout
#[derive(Debug)]
pub struct Layout {
    layout: NonNull<libflashrom_sys::flashrom_layout>,
}

impl Layout {
    /// Create an empty [`Layout`]
    ///
    /// # Panics
    ///
    /// Panics if flashrom_layout_new returns 0 and a NULL pointer.
    pub fn new() -> std::result::Result<Layout, ErrorCode> {
        let mut layout: *mut libflashrom_sys::flashrom_layout = null_mut();
        let err = unsafe { libflashrom_sys::flashrom_layout_new(&mut layout) };
        if err != 0 {
            Err(ErrorCode {
                function: "flashrom_layout_new",
                code: err,
            })
        } else {
            Ok(Layout {
                layout: NonNull::new(layout).expect("flashrom_layout_new returned null"),
            })
        }
    }

    /// Add a region to the [`Layout`]
    ///
    /// Not the region will not be 'included', include_region must be called to include the region.
    ///
    /// # Errors
    ///
    /// This function will return an error if the region is not a valid CString,
    /// or if libflashrom returns an error.
    pub fn add_region<T>(&mut self, region: &str, range: T) -> std::result::Result<(), RegionError>
    where
        T: std::ops::RangeBounds<usize>,
    {
        let range: RangeInternal = range.into();
        let err = {
            let region = CString::new(region)?;
            unsafe {
                libflashrom_sys::flashrom_layout_add_region(
                    self.layout.as_mut(),
                    range.start,
                    range.end(),
                    region.as_ptr(),
                )
            }
        };

        if err != 0 {
            Err(RegionError::ErrorCode(ErrorCode {
                function: "flashrom_layout_add_region",
                code: err,
            }))
        } else {
            Ok(())
        }
    }

    /// Include a region
    ///
    /// # Errors
    ///
    /// This function will return an error if the region is not a valid CString,
    /// or if libflashrom returns an error.
    pub fn include_region(&mut self, region: &str) -> std::result::Result<(), RegionError> {
        let err = {
            let region = CString::new(region)?;
            unsafe {
                libflashrom_sys::flashrom_layout_include_region(
                    self.layout.as_mut(),
                    region.as_ptr(),
                )
            }
        };
        if err != 0 {
            Err(RegionError::ErrorCode(ErrorCode {
                function: "flashrom_layout_include_region",
                code: err,
            }))
        } else {
            Ok(())
        }
    }

    /// Exclude a region
    ///
    /// # Errors
    ///
    /// This function will return an error if the region is not a valid CString,
    /// or if libflashrom returns an error.
    pub fn exclude_region(&mut self, region: &str) -> std::result::Result<(), RegionError> {
        let err = {
            let region = CString::new(region)?;
            unsafe {
                libflashrom_sys::flashrom_layout_exclude_region(
                    self.layout.as_mut(),
                    region.as_ptr(),
                )
            }
        };
        if err != 0 {
            Err(RegionError::ErrorCode(ErrorCode {
                function: "flashrom_layout_exclude_region",
                code: err,
            }))
        } else {
            Ok(())
        }
    }

    /// Get the [`Range`] for the given region
    ///
    /// # Errors
    ///
    /// This function will return an error if the region is not a valid CString,
    /// or if libflashrom returns an error.
    pub fn get_region_range(&mut self, region: &str) -> std::result::Result<Range, RegionError> {
        let mut start: std::os::raw::c_uint = 0;
        let mut len: std::os::raw::c_uint = 0;
        let err = {
            let region = CString::new(region)?;
            unsafe {
                libflashrom_sys::flashrom_layout_get_region_range(
                    self.layout.as_mut(),
                    region.as_ptr(),
                    &mut start,
                    &mut len,
                )
            }
        };
        if err != 0 {
            Err(RegionError::ErrorCode(ErrorCode {
                function: "flashrom_layout_get_region_range",
                code: err,
            }))
        } else {
            // should be safe to assume sizeof(size_t) >= sizeof(unsigned int)
            // TODO: fix after https://review.coreboot.org/c/flashrom/+/65944
            Ok(start.try_into().unwrap()..(start + len).try_into().unwrap())
        }
    }
}

// TODO this will be replaced with an API implementation: https://review.coreboot.org/c/flashrom/+/65999
impl std::str::FromStr for Layout {
    type Err = Box<dyn error::Error>;

    /// This will attempt to parse the [`Layout`] file format into a [`Layout`]
    ///
    /// The format is documented in the flashrom man page.
    fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
        let mut ret = Layout::new()?;

        // format is hex:hex name
        // flashrom layout.c seems to allow any characters in the name string
        // I am restricting here to non whitespace
        let re = Regex::new(r"^([0-9A-Za-z]+):([0-9A-Za-z]+)\s+(\S+)$").unwrap();

        // we dont use captures_iter else we would ignore incorrect lines
        for line in s.lines() {
            let (start, end, name) = match re.captures(line) {
                Some(caps) => (
                    caps.get(1).unwrap(),
                    caps.get(2).unwrap(),
                    caps.get(3).unwrap(),
                ),
                None => Err(ParseLayoutError(format!("failed to parse: {:?}", line)))?,
            };
            let start = usize::from_str_radix(start.as_str(), 16)?;
            let end = usize::from_str_radix(end.as_str(), 16)?;
            ret.add_region(name.as_str(), start..=end)?;
        }

        Ok(ret)
    }
}

impl Drop for Layout {
    fn drop(&mut self) {
        unsafe {
            libflashrom_sys::flashrom_layout_release(self.layout.as_mut());
        }
    }
}

#[cfg(test)]
mod tests {
    use gag::BufferRedirect;
    use std::io::Read;

    use super::flashrom_version_info;
    use super::set_log_level;
    use super::Chip;
    use super::ChipInitError;
    use super::InitError;
    use crate::set_log_function;
    use crate::Layout;
    use crate::Programmer;
    use crate::WriteProtectCfg;

    // flashrom contains global state, which prevents correct initialisation of
    // a second programmer or probing of a second chip. Run all unit tests in
    // forked subprocesses to avoid this issue.
    use rusty_fork::rusty_fork_test;
    rusty_fork_test! {

        #[test]
        fn version() {
            // There is no version requirement yet, but for example:
            // assert!(flashrom_version_info().contains("v1.2"))
            assert!(!flashrom_version_info().unwrap().is_empty())
        }

        #[test]
        fn only_one_programmer() {
            {
                let _1 = Programmer::new("dummy", Some("emulate=W25Q128FV")).unwrap();
                // Only one programmer can be initialised at a time.
                assert_eq!(Programmer::new("dummy", Some("emulate=W25Q128FV")).unwrap_err(), InitError::DuplicateInit)
            }
            // Only one programmer can ever be initialised
            assert_eq!(Programmer::new("dummy", Some("emulate=W25Q128FV")).unwrap_err(), InitError::DuplicateInit)
        }

        #[test]
        fn programmer_bad_cstring_name() {
            assert!(matches!(Programmer::new("dummy\0", None).unwrap_err(), InitError::InvalidName(_)))
        }

        #[test]
        fn chip_none() {
            // Not specifying a chip will select one if there is one.
            Chip::new(Programmer::new("dummy", Some("emulate=W25Q128FV")).unwrap(), None).unwrap();
        }

        #[test]
        fn chip_some() {
            // Specifying a valid chip.
            Chip::new(Programmer::new("dummy", Some("emulate=W25Q128FV")).unwrap(), Some("W25Q128.V")).unwrap();
        }

        #[test]
        fn chip_nochip() {
            // Choosing a non existent chip fails.
            assert_eq!(
                Chip::new(Programmer::new("dummy", None).unwrap(), Some("W25Q128.V")).unwrap_err(),
                ChipInitError::NoChipError
            );
        }

        #[test]
        fn logging_stderr() {
            let mut buf = BufferRedirect::stderr().unwrap();
            let mut fc = Chip::new(Programmer::new("dummy", Some("emulate=W25Q128FV")).unwrap(), Some("W25Q128.V")).unwrap();

            set_log_level(Some(libflashrom_sys::FLASHROM_MSG_INFO));
            fc.image_read(None).unwrap();
            let mut stderr = String::new();
            if buf.read_to_string(&mut stderr).unwrap() == 0 {
                panic!("stderr empty when it should have some messages");
            }

            set_log_level(None);
            fc.image_read(None).unwrap();
            if buf.read_to_string(&mut stderr).unwrap() != 0 {
                panic!("stderr not empty when it should be silent");
            }
        }

        #[test]
        fn logging_custom() {
            // Check that a custom logging callback works
            static mut BUF: String = String::new();
            fn logger(
                _: libflashrom_sys::flashrom_log_level,
                format: &str,
            ) {
                unsafe {BUF.push_str(format)}
            }
            set_log_function(logger);
            set_log_level(Some(libflashrom_sys::FLASHROM_MSG_SPEW));
            Chip::new(Programmer::new("dummy", Some("emulate=W25Q128FV")).unwrap(), Some("W25Q128.V")).unwrap();
            assert_ne!(unsafe{BUF.len()}, 0);
        }

        #[test]
        fn flashchip() {
            // basic tests of the flashchip methods
            let mut fc = Chip::new(Programmer::new("dummy", Some("emulate=W25Q128FV")).unwrap(), Some("W25Q128.V")).unwrap();
            fc.get_size();

            let mut wp = fc.get_wp().unwrap();
            wp.set_mode(libflashrom_sys::flashrom_wp_mode::FLASHROM_WP_MODE_DISABLED);
            fc.set_wp(&wp).unwrap();
            fc.get_wp_ranges().unwrap();

            fn test_layout() -> Layout {
                let mut layout = Layout::new().unwrap();
                layout.add_region("xyz", 100..200).unwrap();
                layout.include_region("xyz").unwrap();
                layout.add_region("abc", 100..200).unwrap();
                layout
            }

            fc.image_read(None).unwrap();
            fc.image_read(Some(test_layout())).unwrap();

            let mut buf = vec![0; fc.get_size()];
            fc.image_write(&mut buf, None).unwrap();
            fc.image_write(&mut buf, Some(test_layout())).unwrap();

            fc.image_verify(&buf, None).unwrap();
            fc.image_verify(&buf, Some(test_layout())).unwrap();

            fc.erase().unwrap();
        }

        #[test]
        fn write_protect() {
            let mut wp = WriteProtectCfg::new().unwrap();
            wp.set_mode(libflashrom_sys::flashrom_wp_mode::FLASHROM_WP_MODE_DISABLED);
            wp.set_range(100..200);
            assert_eq!(wp.get_mode(), libflashrom_sys::flashrom_wp_mode::FLASHROM_WP_MODE_DISABLED);
            assert_eq!(wp.get_range(), 100..200);
        }
    }
}
