// 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::ast::{
        self, Attrs, BanjoAst, Constant, Decl, EnumVariant, Ident, Method, StructField, UnionField,
    },
    crate::backends::util::to_c_name,
    crate::backends::Backend,
    anyhow::{format_err, Error},
    std::io,
    std::iter,
};

pub struct CBackend<'a, W: io::Write> {
    w: &'a mut W,
}

impl<'a, W: io::Write> CBackend<'a, W> {
    pub fn new(w: &'a mut W) -> Self {
        CBackend { w }
    }
}

pub fn get_doc_comment(attrs: &ast::Attrs, tabs: usize) -> String {
    for attr in attrs.0.iter() {
        if attr.key == "Doc" {
            if let Some(ref val) = attr.val {
                let tabs: String = iter::repeat(' ').take(tabs * 4).collect();
                return val
                    .trim_end()
                    .split("\n")
                    .map(|line| format!("{}//{}\n", tabs, line))
                    .collect();
            }
        }
    }
    "".to_string()
}

fn ty_to_c_str(ast: &ast::BanjoAst, ty: &ast::Ty) -> Result<String, Error> {
    match ty {
        ast::Ty::Bool => Ok(String::from("bool")),
        ast::Ty::Int8 => Ok(String::from("int8_t")),
        ast::Ty::Int16 => Ok(String::from("int16_t")),
        ast::Ty::Int32 => Ok(String::from("int32_t")),
        ast::Ty::Int64 => Ok(String::from("int64_t")),
        ast::Ty::UInt8 => Ok(String::from("uint8_t")),
        ast::Ty::UInt16 => Ok(String::from("uint16_t")),
        ast::Ty::UInt32 => Ok(String::from("uint32_t")),
        ast::Ty::UInt64 => Ok(String::from("uint64_t")),
        ast::Ty::USize => Ok(String::from("size_t")),
        ast::Ty::Float32 => Ok(String::from("float")),
        ast::Ty::Float64 => Ok(String::from("double")),
        ast::Ty::Voidptr => Ok(String::from("void")),
        ast::Ty::Str { .. } => Ok(String::from("char*")),
        ast::Ty::Vector { ref ty, .. } => ty_to_c_str(ast, ty),
        ast::Ty::Array { ref ty, .. } => ty_to_c_str(ast, ty),
        ast::Ty::Identifier { id, .. } => {
            if id.is_base_type() {
                Ok(format!("zx_{}_t", id.name()))
            } else {
                match ast.id_to_type(id) {
                    ast::Ty::Struct | ast::Ty::Union | ast::Ty::Enum => {
                        return Ok(format!("{}_t", to_c_name(id.name())));
                    }
                    ast::Ty::Protocol => {
                        if not_callback(ast, id) {
                            return Ok(format!("{}_protocol_t", to_c_name(id.name())));
                        } else {
                            return Ok(format!("{}_t", to_c_name(id.name())));
                        }
                    }
                    t => return ty_to_c_str(ast, &t),
                }
            }
        }
        ast::Ty::Handle { .. } => Ok(String::from("zx_handle_t")),
        t => Err(format_err!("unknown type in ty_to_c_str {:?}", t)),
    }
}

pub fn array_bounds(ast: &ast::BanjoAst, ty: &ast::Ty) -> Option<String> {
    if let ast::Ty::Array { ref ty, size, .. } = ty {
        return if let Some(bounds) = array_bounds(ast, ty) {
            Some(format!("[{}]{}", size.0, bounds))
        } else {
            Some(format!("[{}]", size.0))
        };
    }
    None
}

fn protocol_to_ops_c_str(ast: &ast::BanjoAst, ty: &ast::Ty) -> Result<String, Error> {
    if let ast::Ty::Identifier { id, .. } = ty {
        if ast.id_to_type(id) == ast::Ty::Protocol {
            return Ok(to_c_name(id.name()) + "_protocol_ops_t");
        }
    }
    Err(format_err!("unknown ident type in protocol_to_ops_c_str {:?}", ty))
}

pub fn not_callback(ast: &ast::BanjoAst, id: &Ident) -> bool {
    if let Some(attributes) = ast.id_to_attributes(id) {
        if let Some(layout) = attributes.get_attribute("Layout") {
            if layout == "ddk-callback" {
                return false;
            }
        }
    }
    true
}

fn size_to_c_str(ty: &ast::Ty, cons: &ast::Constant, ast: &ast::BanjoAst) -> String {
    let Constant(size) = cons;
    match ty {
        ast::Ty::Int8 => String::from(format!("INT8_C({})", size)),
        ast::Ty::Int16 => String::from(format!("INT16_C({})", size)),
        ast::Ty::Int32 => String::from(format!("INT32_C({})", size)),
        ast::Ty::Int64 => String::from(format!("INT64_C({})", size)),
        ast::Ty::UInt8 => String::from(format!("UINT8_C({})", size)),
        ast::Ty::UInt16 => String::from(format!("UINT16_C({})", size)),
        ast::Ty::UInt32 => String::from(format!("UINT32_C({})", size)),
        ast::Ty::UInt64 => String::from(format!("UINT64_C({})", size)),
        ast::Ty::USize | ast::Ty::Bool | ast::Ty::Str { .. } => size.clone(),
        ast::Ty::Identifier { id, reference: _ } => {
            let decl = ast.id_to_decl(id).expect(format!("id: {:?}", id).as_str());
            if let Decl::Enum { ty: enum_ty, variants, .. } = decl {
                for variant in variants {
                    if variant.name == *size {
                        return size_to_c_str(enum_ty, &variant.value, ast);
                    }
                }
            }
            panic!("don't handle this kind of identifier: {:?}", id);
        }
        s => panic!("don't handles this sized const: {}", s),
    }
}

pub fn name_buffer(ty: &str) -> &'static str {
    if ty == "void" {
        "buffer"
    } else {
        "list"
    }
}

pub fn name_size(ty: &str) -> &'static str {
    if ty == "void" {
        "size"
    } else {
        "count"
    }
}

fn struct_attrs_to_c_str(attributes: &Attrs) -> String {
    attributes
        .0
        .iter()
        .filter_map(|a| match a.key.as_ref() {
            "Packed" => Some("__PACKED"),
            _ => None,
        })
        .collect::<Vec<_>>()
        .join(" ")
}

fn field_to_c_str(
    attrs: &Attrs,
    ty: &ast::Ty,
    ident: &Ident,
    indent: &str,
    ast: &ast::BanjoAst,
) -> Result<String, Error> {
    let mut accum = String::new();
    accum.push_str(get_doc_comment(attrs, 1).as_str());
    let prefix = if ty.is_reference() { "" } else { "const " };
    match ty {
        ast::Ty::Vector { ty: ref inner_ty, .. } => {
            let ty_name = ty_to_c_str(ast, &ty)?;
            // TODO(surajmalhotra): Support multi-dimensional vectors.
            let ptr = if inner_ty.is_reference() { "*" } else { "" };
            accum.push_str(
                format!(
                    "{indent}{prefix}{ty}{ptr}* {c_name}_{buffer};\n\
                     {indent}size_t {c_name}_{size};",
                    indent = indent,
                    buffer = name_buffer(&ty_name),
                    size = name_size(&ty_name),
                    c_name = to_c_name(ident.name()),
                    prefix = prefix,
                    ty = ty_name,
                    ptr = ptr,
                )
                .as_str(),
            );
        }
        ast::Ty::Array { .. } => {
            let bounds = array_bounds(ast, &ty).unwrap();
            accum.push_str(
                format!(
                    "{indent}{ty} {c_name}{bounds};",
                    indent = indent,
                    c_name = to_c_name(ident.name()),
                    bounds = bounds,
                    ty = ty_to_c_str(ast, &ty)?
                )
                .as_str(),
            );
        }
        ast::Ty::Str { ref size, .. } => {
            if let Some(size) = size {
                accum.push_str(
                    format!(
                        "{indent}char {c_name}[{size}];",
                        indent = indent,
                        c_name = to_c_name(ident.name()),
                        size = size,
                    )
                    .as_str(),
                );
            } else {
                accum.push_str(
                    format!(
                        "{indent}{prefix}{ty} {c_name};",
                        indent = indent,
                        c_name = to_c_name(ident.name()),
                        prefix = prefix,
                        ty = ty_to_c_str(ast, &ty)?
                    )
                    .as_str(),
                );
            }
        }
        _ => {
            accum.push_str(
                format!(
                    "{indent}{ty} {c_name};",
                    indent = indent,
                    c_name = to_c_name(ident.name()),
                    ty = ty_to_c_str(ast, &ty)?
                )
                .as_str(),
            );
        }
    }
    Ok(accum)
}

fn get_first_param(ast: &BanjoAst, method: &ast::Method) -> Result<(bool, String), Error> {
    // Return parameter if a primitive type.
    if method.out_params.get(0).map_or(false, |p| p.1.is_primitive(&ast)) {
        Ok((true, ty_to_c_str(ast, &method.out_params[0].1)?))
    } else {
        Ok((false, "void".to_string()))
    }
}
fn get_in_params(m: &ast::Method, transform: bool, ast: &BanjoAst) -> Result<Vec<String>, Error> {
    m.in_params
        .iter()
        .map(|(name, ty)| {
            match ty {
                ast::Ty::Identifier { id, .. } => {
                    if id.is_base_type() {
                        let ty_name = ty_to_c_str(ast, ty).unwrap();
                        return Ok(format!("{} {}", ty_name, to_c_name(name)));
                    }
                    match ast.id_to_type(id) {
                        ast::Ty::Protocol => {
                            let ty_name = ty_to_c_str(ast, ty).unwrap();
                            if transform && not_callback(ast, id) {
                                let ty_name = protocol_to_ops_c_str(ast, ty).unwrap();
                                Ok(format!(
                                    "void* {name}_ctx, {ty_name}* {name}_ops",
                                    ty_name = ty_name,
                                    name = to_c_name(name)
                                ))
                            } else {
                                Ok(format!("const {}* {}", ty_name, to_c_name(name)))
                            }
                        }
                        ast::Ty::Struct | ast::Ty::Union => {
                            let ty_name = ty_to_c_str(ast, ty).unwrap();
                            // TODO: Using nullability to determine whether param is mutable is a hack.
                            let prefix = if ty.is_reference() { "" } else { "const " };
                            Ok(format!("{}{}* {}", prefix, ty_name, to_c_name(name)))
                        }
                        ast::Ty::Enum => {
                            Ok(format!("{} {}", ty_to_c_str(ast, ty).unwrap(), to_c_name(name)))
                        }
                        ast::Ty::Bool
                        | ast::Ty::Int8
                        | ast::Ty::Int16
                        | ast::Ty::Int32
                        | ast::Ty::Int64
                        | ast::Ty::UInt8
                        | ast::Ty::UInt16
                        | ast::Ty::UInt32
                        | ast::Ty::UInt64
                        | ast::Ty::USize
                        | ast::Ty::Voidptr => {
                            Ok(format!("{} {}", ty_to_c_str(ast, ty).unwrap(), to_c_name(name)))
                        }
                        e => Err(format_err!("unsupported: {}", e)),
                    }
                }
                ast::Ty::Str { .. } => {
                    Ok(format!("const {} {}", ty_to_c_str(ast, ty).unwrap(), to_c_name(name)))
                }
                ast::Ty::Array { .. } => {
                    let bounds = array_bounds(ast, ty).unwrap();
                    let ty = ty_to_c_str(ast, ty).unwrap();
                    Ok(format!(
                        "const {ty} {name}{bounds}",
                        bounds = bounds,
                        ty = ty,
                        name = to_c_name(name)
                    ))
                }
                ast::Ty::Vector { ty: inner_ty, .. } => {
                    let ty = ty_to_c_str(ast, ty).unwrap();
                    // TODO(surajmalhotra): Support multi-dimensional vectors.
                    let ptr = if inner_ty.is_reference() { "*" } else { "" };
                    Ok(format!(
                        "const {ty}{ptr}* {name}_{buffer}, size_t {name}_{size}",
                        buffer = name_buffer(&ty),
                        size = name_size(&ty),
                        ty = ty,
                        ptr = ptr,
                        name = to_c_name(name)
                    ))
                }
                _ => Ok(format!("{} {}", ty_to_c_str(ast, ty).unwrap(), to_c_name(name))),
            }
        })
        .collect()
}

fn get_out_params(
    m: &ast::Method,
    name: &str,
    ast: &BanjoAst,
) -> Result<(Vec<String>, String), Error> {
    if m.attributes.has_attribute("Async") {
        return Ok((
            vec![
                format!(
                    "{protocol_name}_{method_name}_callback callback",
                    protocol_name = to_c_name(name),
                    method_name = to_c_name(&m.name)
                ),
                "void* cookie".to_string(),
            ],
            "void".to_string(),
        ));
    }

    let (skip, return_param) = get_first_param(ast, m)?;
    let skip_amt = if skip { 1 } else { 0 };

    Ok((m.out_params.iter().skip(skip_amt).map(|(name, ty)| {
        let nullable = if ty.is_reference() { "*" } else { "" };
        let ty_name = ty_to_c_str(ast, ty).unwrap();
        match ty {
            ast::Ty::Protocol => format!("const {}* {}", ty_name, to_c_name(name)),
            ast::Ty::Array { .. } => {
                let bounds = array_bounds(ast, ty).unwrap();
                let ty = ty_to_c_str(ast, ty).unwrap();
                format!(
                    "{ty} out_{name}{bounds}",
                    bounds = bounds,
                    ty = ty,
                    name = to_c_name(name)
                )
            }
            ast::Ty::Vector { ty: inner_ty, .. } => {
                // TODO(surajmalhotra): Support multi-dimensional vectors.
                let ptr = if inner_ty.is_reference() { "*" } else { "" };
                if ty.is_reference() {
                    format!("{ty}{ptr}** out_{name}_{buffer}, size_t* {name}_{size}",
                            buffer = name_buffer(&ty_name),
                            size = name_size(&ty_name),
                            ty = ty_name,
                            ptr = ptr,
                            name = to_c_name(name))
                } else {
                    format!("{ty}{ptr}* out_{name}_{buffer}, size_t {name}_{size}, size_t* out_{name}_actual",
                            buffer = name_buffer(&ty_name),
                            size = name_size(&ty_name),
                            ty = ty_name,
                            ptr = ptr,
                            name = to_c_name(name))
                }
            },
            ast::Ty::Str {..} => {
                format!("{ty} out_{c_name}, size_t {c_name}_capacity",
                        ty = ty_name, c_name = to_c_name(name))
            }
            ast::Ty::Handle {..} => format!("{}* out_{}", ty_name, to_c_name(name)),
            _ => format!("{}{}* out_{}", ty_name, nullable, to_c_name(name))
        }
    }).collect(), return_param))
}

fn get_in_args(m: &ast::Method, ast: &BanjoAst) -> Result<Vec<String>, Error> {
    Ok(m.in_params
        .iter()
        .map(|(name, ty)| match ty {
            ast::Ty::Vector { .. } => {
                let ty = ty_to_c_str(ast, ty).unwrap();
                format!(
                    "{name}_{buffer}, {name}_{size}",
                    buffer = name_buffer(&ty),
                    size = name_size(&ty),
                    name = to_c_name(name)
                )
            }
            _ => format!("{}", to_c_name(name)),
        })
        .collect())
}

fn get_out_args(m: &ast::Method, ast: &BanjoAst) -> Result<(Vec<String>, bool), Error> {
    if m.attributes.has_attribute("Async") {
        return Ok((vec!["callback".to_string(), "cookie".to_string()], false));
    }

    let (skip, _) = get_first_param(ast, m)?;
    let skip_amt = if skip { 1 } else { 0 };
    Ok((
        m.out_params
            .iter()
            .skip(skip_amt)
            .map(|(name, ty)| match ty {
                ast::Ty::Protocol { .. } => format!("{}", to_c_name(name)),
                ast::Ty::Vector { .. } => {
                    let ty_name = ty_to_c_str(ast, ty).unwrap();
                    if ty.is_reference() {
                        format!(
                            "out_{name}_{buffer}, {name}_{size}",
                            buffer = name_buffer(&ty_name),
                            size = name_size(&ty_name),
                            name = to_c_name(name)
                        )
                    } else {
                        format!(
                            "out_{name}_{buffer}, {name}_{size}, out_{name}_actual",
                            buffer = name_buffer(&ty_name),
                            size = name_size(&ty_name),
                            name = to_c_name(name)
                        )
                    }
                }
                ast::Ty::Str { .. } => {
                    format!("out_{c_name}, {c_name}_capacity", c_name = to_c_name(name))
                }
                _ => format!("out_{}", to_c_name(name)),
            })
            .collect(),
        skip,
    ))
}

enum ProtocolType {
    Callback,
    Interface,
    Protocol,
}

impl From<&Attrs> for ProtocolType {
    fn from(attributes: &Attrs) -> Self {
        if let Some(layout) = attributes.get_attribute("Layout") {
            if layout == "ddk-callback" {
                ProtocolType::Callback
            } else if layout == "ddk-interface" {
                ProtocolType::Interface
            } else if layout == "ddk-protocol" {
                ProtocolType::Protocol
            } else {
                panic!("Unknown layout attribute: {}", layout);
            }
        } else {
            ProtocolType::Protocol
        }
    }
}

impl<'a, W: io::Write> CBackend<'a, W> {
    fn codegen_enum_decl(
        &self,
        _attributes: &Attrs,
        name: &Ident,
        ty: &ast::Ty,
        variants: &Vec<EnumVariant>,
        ast: &BanjoAst,
    ) -> Result<String, Error> {
        let enum_defines = variants
            .iter()
            .map(|v| {
                Ok(format!(
                    "#define {c_name}_{v_name} {c_size}",
                    c_name = to_c_name(name.name()).to_uppercase(),
                    v_name = v.name.to_uppercase().trim(),
                    c_size = size_to_c_str(ty, &v.value, ast)
                ))
            })
            .collect::<Result<Vec<_>, Error>>()?
            .join("\n");
        Ok(format!(
            "typedef {ty} {c_name}_t;\n{enum_defines}",
            c_name = to_c_name(name.name()),
            ty = ty_to_c_str(ast, ty)?,
            enum_defines = enum_defines
        ))
    }

    fn codegen_constant_decl(
        &self,
        attributes: &Attrs,
        name: &Ident,
        ty: &ast::Ty,
        value: &Constant,
        ast: &BanjoAst,
    ) -> Result<String, Error> {
        let mut accum = String::new();
        accum.push_str(get_doc_comment(attributes, 0).as_str());
        accum.push_str(
            format!(
                "#define {name} {value}",
                name = name.name().trim(),
                value = size_to_c_str(ty, value, ast)
            )
            .as_str(),
        );
        Ok(accum)
    }

    fn codegen_union_decl(
        &self,
        _attributes: &Attrs,
        name: &Ident,
        _fields: &Vec<UnionField>,
        _ast: &BanjoAst,
    ) -> Result<String, Error> {
        Ok(format!("typedef union {c_name} {c_name}_t;", c_name = to_c_name(name.name())))
    }

    fn codegen_union_def(
        &self,
        attributes: &Attrs,
        name: &Ident,
        fields: &Vec<UnionField>,
        ast: &BanjoAst,
    ) -> Result<String, Error> {
        let attrs = struct_attrs_to_c_str(attributes);
        let members = fields
            .iter()
            .map(|f| match f.ty {
                ast::Ty::Vector { .. } => Err(format_err!("unsupported for UnionField: {:?}", f)),
                _ => field_to_c_str(&f.attributes, &f.ty, &f.ident, "    ", &ast),
            })
            .collect::<Result<Vec<_>, Error>>()?
            .join("\n");
        let mut accum = String::new();
        accum.push_str(get_doc_comment(attributes, 0).as_str());
        accum.push_str(
            format!(
                include_str!("templates/c/struct.h"),
                c_name = to_c_name(name.name()),
                decl = "union",
                attrs = if attrs.is_empty() { "".to_string() } else { format!(" {}", attrs) },
                members = members
            )
            .as_str(),
        );
        Ok(accum)
    }

    fn codegen_struct_decl(
        &self,
        _attributes: &Attrs,
        name: &Ident,
        fields: &Vec<StructField>,
        _ast: &BanjoAst,
    ) -> Result<String, Error> {
        // TODO(surajmalhotra): Remove this hack once we no longer include C types.
        if fields.len() == 0 {
            return Ok("".to_string());
        }
        Ok(format!("typedef struct {c_name} {c_name}_t;", c_name = to_c_name(name.name())))
    }

    fn codegen_struct_def(
        &self,
        attributes: &Attrs,
        name: &Ident,
        fields: &Vec<StructField>,
        ast: &BanjoAst,
    ) -> Result<String, Error> {
        // TODO(surajmalhotra): Remove this hack once we no longer include C types.
        if fields.len() == 0 {
            return Ok("".to_string());
        }
        let attrs = struct_attrs_to_c_str(attributes);
        let members = fields
            .iter()
            .map(|f| field_to_c_str(&f.attributes, &f.ty, &f.ident, "    ", &ast))
            .collect::<Result<Vec<_>, Error>>()?
            .join("\n");
        let mut accum = String::new();
        accum.push_str(get_doc_comment(attributes, 0).as_str());
        accum.push_str(
            format!(
                include_str!("templates/c/struct.h"),
                c_name = to_c_name(name.name()),
                decl = "struct",
                attrs = if attrs.is_empty() { "".to_string() } else { format!(" {}", attrs) },
                members = members
            )
            .as_str(),
        );
        Ok(accum)
    }

    fn codegen_protocol_def2(
        &self,
        name: &str,
        methods: &Vec<ast::Method>,
        ast: &BanjoAst,
    ) -> Result<String, Error> {
        let fns = methods
            .iter()
            .map(|m| {
                let (out_params, return_param) = get_out_params(&m, name, ast)?;
                let in_params = get_in_params(&m, false, ast)?;

                let params = iter::once("void* ctx".to_string())
                    .chain(in_params)
                    .chain(out_params)
                    .collect::<Vec<_>>()
                    .join(", ");
                Ok(format!(
                    "    {return_param} (*{fn_name})({params});",
                    return_param = return_param,
                    params = params,
                    fn_name = to_c_name(m.name.as_str())
                ))
            })
            .collect::<Result<Vec<_>, Error>>()?
            .join("\n");
        Ok(format!(include_str!("templates/c/protocol_ops.h"), c_name = to_c_name(name), fns = fns))
    }

    fn codegen_helper_def(
        &self,
        name: &str,
        methods: &Vec<ast::Method>,
        ast: &BanjoAst,
    ) -> Result<String, Error> {
        methods
            .iter()
            .map(|m| {
                let mut accum = String::new();
                accum.push_str(get_doc_comment(&m.attributes, 0).as_str());

                let (out_params, return_param) = get_out_params(&m, name, ast)?;
                let in_params = get_in_params(&m, true, ast)?;

                let first_param = format!("const {}_protocol_t* proto", to_c_name(name));

                let params = iter::once(first_param)
                    .chain(in_params)
                    .chain(out_params)
                    .collect::<Vec<_>>()
                    .join(", ");

                accum.push_str(
                    format!(
                        "static inline {return_param} {protocol_name}_{fn_name}({params}) {{\n",
                        return_param = return_param,
                        params = params,
                        protocol_name = to_c_name(name),
                        fn_name = to_c_name(m.name.as_str())
                    )
                    .as_str(),
                );

                let (out_args, skip) = get_out_args(&m, ast)?;
                let in_args = get_in_args(&m, ast)?;

                let proto_args = m
                    .in_params
                    .iter()
                    .filter_map(|(name, ty)| {
                        if let ast::Ty::Identifier { id, .. } = ty {
                            if ast.id_to_type(id) == ast::Ty::Protocol && not_callback(ast, id) {
                                return Some((to_c_name(name), ty_to_c_str(ast, ty).unwrap()));
                            }
                        }
                        None
                    })
                    .collect::<Vec<_>>();
                for (name, ty) in proto_args.iter() {
                    accum.push_str(
                        format!(
                            include_str!("templates/c/proto_transform.h"),
                            ty = ty,
                            name = name
                        )
                        .as_str(),
                    );
                }

                let args = iter::once("proto->ctx".to_string())
                    .chain(in_args)
                    .chain(out_args)
                    .collect::<Vec<_>>()
                    .join(", ");

                let return_statement = if skip { "return " } else { "" };

                accum.push_str(
                    format!(
                        "    {return_statement}proto->ops->{fn_name}({args});\n",
                        return_statement = return_statement,
                        args = args,
                        fn_name = to_c_name(m.name.as_str())
                    )
                    .as_str(),
                );
                accum.push_str("}\n");
                Ok(accum)
            })
            .collect::<Result<Vec<_>, Error>>()
            .map(|x| x.join("\n"))
    }

    fn codegen_protocol_def(
        &self,
        attributes: &Attrs,
        name: &Ident,
        methods: &Vec<Method>,
        ast: &BanjoAst,
    ) -> Result<String, Error> {
        Ok(match ProtocolType::from(attributes) {
            ProtocolType::Interface | ProtocolType::Protocol => format!(
                include_str!("templates/c/protocol.h"),
                protocol_name = to_c_name(name.name()),
                protocol_def = self.codegen_protocol_def2(name.name(), methods, ast)?,
                helper_def = self.codegen_helper_def(name.name(), methods, ast)?
            ),
            ProtocolType::Callback => {
                let m = methods.get(0).ok_or(format_err!("callback has no methods"))?;
                let (out_params, return_param) = get_out_params(&m, name.name(), ast)?;
                let in_params = get_in_params(&m, false, ast)?;

                let params = iter::once("void* ctx".to_string())
                    .chain(in_params)
                    .chain(out_params)
                    .collect::<Vec<_>>()
                    .join(", ");
                let method = format!(
                    "{return_param} (*{fn_name})({params})",
                    return_param = return_param,
                    params = params,
                    fn_name = to_c_name(m.name.as_str())
                );
                format!(
                    include_str!("templates/c/callback.h"),
                    callback_name = to_c_name(name.name()),
                    callback = method,
                )
            }
        })
    }

    fn codegen_async_decls(
        &self,
        name: &Ident,
        methods: &Vec<Method>,
        ast: &BanjoAst,
    ) -> Result<String, Error> {
        Ok(methods
            .iter()
            .filter(|method| method.attributes.has_attribute("Async"))
            .map(|method| {
                let method = ast::Method {
                    attributes: method.attributes.clone(),
                    name: method.name.clone(),
                    in_params: method.out_params.clone(),
                    out_params: Vec::new(),
                };
                let in_params = get_in_params(&method, true, ast)?;
                let params = iter::once("void* ctx".to_string())
                    .chain(in_params)
                    .collect::<Vec<_>>()
                    .join(", ");
                Ok(format!(
                    "typedef void (*{protocol_name}_{method_name}_callback)({params});\n",
                    protocol_name = to_c_name(name.name()),
                    method_name = to_c_name(method.name.as_str()),
                    params = params
                ))
            })
            .collect::<Result<Vec<_>, Error>>()?
            .join(""))
    }

    fn codegen_protocol_decl(
        &self,
        attributes: &Attrs,
        name: &Ident,
        methods: &Vec<Method>,
        ast: &BanjoAst,
    ) -> Result<String, Error> {
        Ok(match ProtocolType::from(attributes) {
            ProtocolType::Interface | ProtocolType::Protocol => format!(
                "{async_decls}typedef struct {c_name}_protocol {c_name}_protocol_t;",
                async_decls = self.codegen_async_decls(name, methods, ast)?,
                c_name = to_c_name(name.name())
            ),
            ProtocolType::Callback => {
                format!("typedef struct {c_name} {c_name}_t;", c_name = to_c_name(name.name()))
            }
        })
    }

    fn codegen_includes(&self, ast: &BanjoAst) -> Result<String, Error> {
        Ok(ast
            .namespaces
            .iter()
            .filter(|n| *n.0 != ast.primary_namespace)
            .filter(|n| *n.0 != "zx")
            .map(|n| format!("#include <{}.h>", n.0.replace('.', "/")))
            .collect::<Vec<_>>()
            .join("\n"))
    }
}

impl<'a, W: io::Write> Backend<'a, W> for CBackend<'a, W> {
    fn codegen(&mut self, ast: BanjoAst) -> Result<(), Error> {
        self.w.write_fmt(format_args!(
            include_str!("templates/c/header.h"),
            includes = self.codegen_includes(&ast)?,
            primary_namespace = ast.primary_namespace
        ))?;

        let decl_order = ast.validate_declaration_deps()?;

        let declarations = decl_order
            .iter()
            .filter_map(|decl| match decl {
                Decl::Struct { attributes, name, fields } => {
                    Some(self.codegen_struct_decl(attributes, name, fields, &ast))
                }
                Decl::Union { attributes, name, fields } => {
                    Some(self.codegen_union_decl(attributes, name, fields, &ast))
                }
                Decl::Enum { attributes, name, ty, variants } => {
                    Some(self.codegen_enum_decl(attributes, name, ty, variants, &ast))
                }
                Decl::Constant { attributes, name, ty, value } => {
                    Some(self.codegen_constant_decl(attributes, name, ty, value, &ast))
                }
                Decl::Protocol { attributes, name, methods } => {
                    Some(self.codegen_protocol_decl(attributes, name, methods, &ast))
                }
                Decl::Alias(_to, _from) => None,
                Decl::Resource { .. } => None,
            })
            .collect::<Result<Vec<_>, Error>>()?
            .join("\n");

        let definitions = decl_order
            .iter()
            .filter_map(|decl| match decl {
                Decl::Struct { attributes, name, fields } => {
                    Some(self.codegen_struct_def(attributes, name, fields, &ast))
                }
                Decl::Union { attributes, name, fields } => {
                    Some(self.codegen_union_def(attributes, name, fields, &ast))
                }
                Decl::Enum { .. } => None,
                Decl::Constant { .. } => None,
                Decl::Protocol { attributes, name, methods } => {
                    Some(self.codegen_protocol_def(attributes, name, methods, &ast))
                }
                Decl::Alias(_to, _from) => None,
                Decl::Resource { .. } => None,
            })
            .collect::<Result<Vec<_>, Error>>()?
            .join("\n");

        self.w.write_fmt(format_args!(
            include_str!("templates/c/body.h"),
            declarations = declarations,
            definitions = definitions,
        ))?;
        Ok(())
    }
}
