// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use crate::parser::{self, ArgKind};

#[derive(Debug)]
pub struct Protocol {
    pub name: String,
    pub copyright: Option<String>,
    pub description: Option<Description>,
    pub interfaces: Vec<Interface>,
}

#[derive(Debug)]
pub struct Description {
    pub summary: String,
    pub description: String,
}

#[derive(Debug)]
pub struct Interface {
    pub name: String,
    pub version: u32,
    pub description: Option<Description>,
    pub requests: Vec<Message>,
    pub events: Vec<Message>,
    pub enums: Vec<Enum>,
}

#[derive(Debug)]
pub struct Message {
    pub name: String,
    pub since: u32,
    pub request_type: Option<String>,
    pub description: Option<Description>,
    pub args: Vec<Arg>,
}

#[derive(Debug)]
pub struct Arg {
    pub name: String,
    pub kind: ArgKind,
    pub summary: Option<String>,
    pub interface: Option<String>,
    pub nullable: bool,
    pub enum_type: Option<String>,
    pub description: Option<Description>,
}

#[derive(Debug)]
pub struct Enum {
    pub name: String,
    pub since: u32,
    pub bitfield: bool,
    pub description: Option<Description>,
    pub entries: Vec<EnumEntry>,
}

#[derive(Debug)]
pub struct EnumEntry {
    pub name: String,
    pub value: i64,
    pub summary: Option<String>,
    pub since: u32,
    pub description: Option<Description>,
}

pub type AstError = String;
pub type AstResult<T> = Result<T, AstError>;

fn build_protocol(node: parser::ParseNode) -> AstResult<Protocol> {
    if let parser::ParseElement::Protocol { name } = node.element {
        let mut copyright: Option<String> = None;
        let mut description: Option<Description> = None;
        let mut interfaces: Vec<Interface> = Vec::new();
        for child in node.children {
            match &child.element {
                parser::ParseElement::Copyright => copyright = Some(build_copyright(child)?),
                parser::ParseElement::Description { .. } => {
                    description = Some(build_description(child)?)
                }
                parser::ParseElement::Interface { .. } => interfaces.push(build_interface(child)?),
                _ => return Err("Unsupported".to_owned()),
            }
        }
        Ok(Protocol {
            name: name,
            copyright,
            description,
            interfaces,
        })
    } else {
        Err("Unexpected Element; expected Protocol".to_owned())
    }
}

fn build_copyright(node: parser::ParseNode) -> AstResult<String> {
    if let Some(copyright) = node.body {
        Ok(copyright)
    } else {
        Err(format!("Unexpected node {:?}", node))
    }
}

fn build_description(node: parser::ParseNode) -> AstResult<Description> {
    if let parser::ParseElement::Description { summary } = node.element {
        Ok(Description {
            summary,
            description: node.body.unwrap_or("".to_owned()),
        })
    } else {
        Err("Invalid node".to_owned())
    }
}

fn build_interface(node: parser::ParseNode) -> AstResult<Interface> {
    if let parser::ParseElement::Interface { name, version } = node.element {
        let mut description: Option<Description> = None;
        let mut requests: Vec<Message> = Vec::new();
        let mut events: Vec<Message> = Vec::new();
        let mut enums: Vec<Enum> = Vec::new();
        for child in node.children {
            match &child.element {
                parser::ParseElement::Description { .. } => {
                    description = Some(build_description(child)?)
                }
                parser::ParseElement::Request { .. } => requests.push(build_request(child)?),
                parser::ParseElement::Event { .. } => events.push(build_event(child)?),
                parser::ParseElement::Enum { .. } => enums.push(build_enum(child)?),
                _ => return Err("Unsupported".to_owned()),
            }
        }
        Ok(Interface {
            name,
            version,
            description,
            requests,
            events,
            enums,
        })
    } else {
        Err("Invalid node".to_owned())
    }
}

fn build_request(node: parser::ParseNode) -> AstResult<Message> {
    if let parser::ParseElement::Request {
        name,
        since,
        request_type,
    } = node.element
    {
        let mut description: Option<Description> = None;
        let mut args: Vec<Arg> = Vec::new();
        for child in node.children {
            match &child.element {
                parser::ParseElement::Description { .. } => {
                    description = Some(build_description(child)?)
                }
                parser::ParseElement::Arg { .. } => args.append(&mut build_arg(child)?),
                _ => return Err("Unsupported".to_owned()),
            }
        }
        Ok(Message {
            name,
            since,
            request_type,
            description,
            args,
        })
    } else {
        Err("Invalid node".to_owned())
    }
}

fn build_event(node: parser::ParseNode) -> AstResult<Message> {
    if let parser::ParseElement::Event { name, since } = node.element {
        let mut description: Option<Description> = None;
        let mut args: Vec<Arg> = Vec::new();
        for child in node.children {
            match &child.element {
                parser::ParseElement::Description { .. } => {
                    description = Some(build_description(child)?)
                }
                parser::ParseElement::Arg { .. } => args.append(&mut build_arg(child)?),
                _ => return Err("Unsupported".to_owned()),
            }
        }
        Ok(Message {
            name,
            since,
            description,
            args,
            request_type: None,
        })
    } else {
        Err("Invalid node".to_owned())
    }
}

fn build_arg(node: parser::ParseNode) -> AstResult<Vec<Arg>> {
    if let parser::ParseElement::Arg {
        name,
        kind,
        summary,
        interface,
        nullable,
        enum_type,
    } = node.element
    {
        let mut description: Option<Description> = None;
        for child in node.children {
            match &child.element {
                parser::ParseElement::Description { .. } => {
                    description = Some(build_description(child)?)
                }
                _ => return Err("Unsupported".to_owned()),
            }
        }
        let arg = Arg {
            name,
            kind,
            summary,
            interface,
            nullable,
            enum_type,
            description,
        };
        // wayland has a slightly different serialization of untyped new_id
        // arguments. Instead of just sending the object id, the interface name
        // and version are sent first. This primarily impacts the
        // wl_registry::bind request.
        if arg.kind == ArgKind::NewId && arg.interface.is_none() {
            Ok(vec![
                Arg {
                    name: format!("{}_interface_name", arg.name),
                    kind: ArgKind::String,
                    summary: None,
                    interface: None,
                    nullable: false,
                    enum_type: None,
                    description: None,
                },
                Arg {
                    name: format!("{}_interface_version", arg.name),
                    kind: ArgKind::Uint,
                    summary: None,
                    interface: None,
                    nullable: false,
                    enum_type: None,
                    description: None,
                },
                arg,
            ])
        } else {
            Ok(vec![arg])
        }
    } else {
        Err("Invalid node".to_owned())
    }
}

fn build_enum(node: parser::ParseNode) -> AstResult<Enum> {
    if let parser::ParseElement::Enum {
        name,
        since,
        bitfield,
    } = node.element
    {
        let mut description: Option<Description> = None;
        let mut entries: Vec<EnumEntry> = Vec::new();
        for child in node.children {
            match &child.element {
                parser::ParseElement::Description { .. } => {
                    description = Some(build_description(child)?)
                }
                parser::ParseElement::EnumEntry { .. } => entries.push(build_enum_entry(child)?),
                _ => return Err("Unsupported".to_owned()),
            }
        }
        Ok(Enum {
            name,
            since,
            bitfield,
            description,
            entries,
        })
    } else {
        Err("Invalid node".to_owned())
    }
}

fn build_enum_entry(node: parser::ParseNode) -> AstResult<EnumEntry> {
    if let parser::ParseElement::EnumEntry {
        name,
        value,
        summary,
        since,
    } = node.element
    {
        let mut description: Option<Description> = None;
        for child in node.children {
            match &child.element {
                parser::ParseElement::Description { .. } => {
                    description = Some(build_description(child)?)
                }
                _ => return Err("Unsupported".to_owned()),
            }
        }
        Ok(EnumEntry {
            name,
            value,
            summary,
            since,
            description,
        })
    } else {
        Err("Invalid node".to_owned())
    }
}

impl Protocol {
    pub fn from_parse_tree(parse_tree: parser::ParseNode) -> AstResult<Protocol> {
        build_protocol(parse_tree)
    }
}
