use paste::paste;

use crate::protocol::packet::PacketBuf;
use crate::target::Target;

pub(self) mod prelude {
    pub use super::ParseCommand;
    pub use crate::common::*;
    pub use crate::protocol::common::hex::{decode_hex, decode_hex_buf, is_hex, HexString};
    pub use crate::protocol::common::thread_id::{
        IdKind, SpecificIdKind, SpecificThreadId, ThreadId,
    };
    pub use crate::protocol::common::Bstr;
    pub use crate::protocol::packet::PacketBuf;
    pub use core::convert::{TryFrom, TryInto};
}

pub trait ParseCommand<'a>: Sized {
    /// Try to parse a packet from the packet buffer.
    fn from_packet(buf: PacketBuf<'a>) -> Option<Self>;
}

// Breakpoint packets are special-cased, as the "Z" packet is parsed differently
// depending on whether or not the target implements the `Agent` extension.
//
// While it's entirely possible to eagerly parse the "Z" packet for bytecode,
// doing so would unnecessary bloat implementations that do not support
// evaluating agent expressions.

macro_rules! commands {
    (
        $(
            $ext:ident $(use $lt:lifetime)? {
                $($name:literal => $mod:ident::$command:ident$(<$lifetime:lifetime>)?,)*
            }
        )*
    ) => {paste! {
        $($(
            #[allow(non_snake_case, non_camel_case_types)]
            pub mod $mod;
        )*)*
        pub mod breakpoint;

        pub mod ext {
            $(
                #[allow(non_camel_case_types)]
                pub enum [<$ext:camel>] $(<$lt>)? {
                    $($command(super::$mod::$command<$($lifetime)?>),)*
                }
            )*

            use super::breakpoint::{BasicBreakpoint, BytecodeBreakpoint};
            #[allow(non_camel_case_types)]
            pub enum Breakpoints<'a> {
                z(BasicBreakpoint<'a>),
                Z(BasicBreakpoint<'a>),
                ZWithBytecode(BytecodeBreakpoint<'a>),
            }

        }

        /// GDB commands
        pub enum Command<'a> {
            $(
                [<$ext:camel>](ext::[<$ext:camel>]$(<$lt>)?),
            )*
            Breakpoints(ext::Breakpoints<'a>),
            Unknown(&'a [u8]),
        }

        impl<'a> Command<'a> {
            pub fn from_packet(
                target: &mut impl Target,
                mut buf: PacketBuf<'a>
            ) -> Option<Command<'a>> {
                // HACK: this locally-scoped trait enables using identifiers
                // that aren't top-level `Target` IDETs to split-up the packet
                // parsing code.
                trait Hack {
                    fn base(&mut self) -> Option<()>;
                    fn single_register_access(&mut self) -> Option<()>;
                    fn reverse_step(&mut self) -> Option<()>;
                    fn reverse_cont(&mut self) -> Option<()>;
                }

                impl<T: Target> Hack for T {
                    fn base(&mut self) -> Option<()> {
                        Some(())
                    }

                    fn single_register_access(&mut self) -> Option<()> {
                        use crate::target::ext::base::BaseOps;
                        match self.base_ops() {
                            BaseOps::SingleThread(ops) => ops.single_register_access().map(drop),
                            BaseOps::MultiThread(ops) => ops.single_register_access().map(drop),
                        }
                    }

                    fn reverse_step(&mut self) -> Option<()> {
                        use crate::target::ext::base::BaseOps;
                        match self.base_ops() {
                            BaseOps::SingleThread(ops) => ops.support_reverse_step().map(drop),
                            BaseOps::MultiThread(ops) => ops.support_reverse_step().map(drop),
                        }
                    }

                    fn reverse_cont(&mut self) -> Option<()> {
                        use crate::target::ext::base::BaseOps;
                        match self.base_ops() {
                            BaseOps::SingleThread(ops) => ops.support_reverse_cont().map(drop),
                            BaseOps::MultiThread(ops) => ops.support_reverse_cont().map(drop),
                        }
                    }
                }

                // TODO?: use tries for more efficient longest prefix matching

                $(
                #[allow(clippy::string_lit_as_bytes)]
                if target.$ext().is_some() {
                    $(
                    if buf.strip_prefix($name.as_bytes()) {
                        crate::__dead_code_marker!($name, "prefix_match");

                        let cmd = $mod::$command::from_packet(buf)?;

                        return Some(
                            Command::[<$ext:camel>](
                                ext::[<$ext:camel>]::$command(cmd)
                            )
                        )
                    }
                    )*
                }
                )*

                if let Some(_breakpoint_ops) = target.breakpoints() {
                    use breakpoint::{BasicBreakpoint, BytecodeBreakpoint};

                    if buf.strip_prefix(b"z") {
                        let cmd = BasicBreakpoint::from_slice(buf.into_body())?;
                        return Some(Command::Breakpoints(ext::Breakpoints::z(cmd)))
                    }

                    if buf.strip_prefix(b"Z") {
                        // TODO: agent bytecode currently unimplemented
                        if true {
                           let cmd = BasicBreakpoint::from_slice(buf.into_body())?;
                            return Some(Command::Breakpoints(ext::Breakpoints::Z(cmd)))
                        } else {
                            let cmd = BytecodeBreakpoint::from_slice(buf.into_body())?;
                            return Some(Command::Breakpoints(ext::Breakpoints::ZWithBytecode(cmd)))
                        }
                    }
                }

                Some(Command::Unknown(buf.into_body()))
            }
        }
    }};
}

commands! {
    base use 'a {
        "?" => question_mark::QuestionMark,
        "c" => _c::c<'a>,
        "D" => _d_upcase::D,
        "g" => _g::g,
        "G" => _g_upcase::G<'a>,
        "H" => _h_upcase::H,
        "k" => _k::k,
        "m" => _m::m<'a>,
        "M" => _m_upcase::M<'a>,
        "qAttached" => _qAttached::qAttached,
        "qfThreadInfo" => _qfThreadInfo::qfThreadInfo,
        "QStartNoAckMode" => _QStartNoAckMode::QStartNoAckMode,
        "qsThreadInfo" => _qsThreadInfo::qsThreadInfo,
        "qSupported" => _qSupported::qSupported<'a>,
        "qXfer:features:read" => _qXfer_features_read::qXferFeaturesRead,
        "s" => _s::s<'a>,
        "T" => _t_upcase::T,
        "vCont" => _vCont::vCont<'a>,
        "vKill" => _vKill::vKill,
    }

    single_register_access use 'a {
        "p" => _p::p,
        "P" => _p_upcase::P<'a>,
    }

    extended_mode use 'a {
        "!" => exclamation_mark::ExclamationMark,
        "QDisableRandomization" => _QDisableRandomization::QDisableRandomization,
        "QEnvironmentHexEncoded" => _QEnvironmentHexEncoded::QEnvironmentHexEncoded<'a>,
        "QEnvironmentReset" => _QEnvironmentReset::QEnvironmentReset,
        "QEnvironmentUnset" => _QEnvironmentUnset::QEnvironmentUnset<'a>,
        "QSetWorkingDir" => _QSetWorkingDir::QSetWorkingDir<'a>,
        "QStartupWithShell" => _QStartupWithShell::QStartupWithShell,
        "R" => _r_upcase::R,
        "vAttach" => _vAttach::vAttach,
        "vRun" => _vRun::vRun<'a>,
    }

    monitor_cmd use 'a {
        "qRcmd" => _qRcmd::qRcmd<'a>,
    }

    section_offsets {
        "qOffsets" => _qOffsets::qOffsets,
    }

    reverse_cont {
        "bc" => _bc::bc,
    }

    reverse_step {
        "bs" => _bs::bs,
    }
}
