use core::io::WriterUtil;
use core::hashmap::linear::LinearSet;

use syntax::abi;
use syntax::ast;
use syntax::codemap::{dummy_sp, dummy_spanned};
use syntax::codemap;
use syntax::ast_util::*;
use syntax::ext::base;
use syntax::ext::build;
use syntax::parse;
use syntax::print::pprust;
use syntax::opt_vec;

use types::*;

struct GenCtx {
    ext_cx: @base::ext_ctxt,
    unnamed_ty: uint,
    keywords: LinearSet<~str>
}

fn empty_generics() -> ast::Generics {
    ast::Generics {
        lifetimes: opt_vec::Empty,
        ty_params: opt_vec::Empty
    }
}

fn rust_id(ctx: &mut GenCtx, name: ~str) -> (~str, bool) {
    if ctx.keywords.contains(&name) {
        (~"_" + name, true)
    } else {
        (name, false)
    }

}

fn unnamed_name(ctx: &mut GenCtx, name: ~str) -> ~str {
    return if name.is_empty() {
        ctx.unnamed_ty += 1;
        fmt!("Unnamed%u", ctx.unnamed_ty)
    } else {
        name
    };
}

fn struct_name(name: ~str) -> ~str {
    fmt!("Struct_%s", name)
}

fn union_name(name: ~str) -> ~str {
    fmt!("Union_%s", name)
}

fn enum_name(name: ~str) -> ~str {
    fmt!("Enum_%s", name)
}

pub fn gen_rs(out: @io::Writer, link: &Option<~str>, globs: &[Global]) {
    let mut ctx = GenCtx { ext_cx: base::mk_ctxt(parse::new_parse_sess(None), ~[]),
                           unnamed_ty: 0,
                           keywords: parse::token::keyword_table()
                         };
    ctx.ext_cx.bt_push(codemap::ExpandedFrom(codemap::CallInfo {
        call_site: dummy_sp(),
        callee: codemap::NameAndSpan {name: ~"top", span: None}
    }));

    let mut fs = ~[];
    let mut vs = ~[];
    let mut gs = ~[];
    for globs.each |g| {
        match *g {
            GOther => {}
            GFunc(_) => fs.push(*g),
            GVar(_) => vs.push(*g),
            _ => gs.push(*g)
        }
    }

    let mut defs = ~[];
    gs = remove_redundent_decl(gs);
    for gs.each |g| {
        match *g {
            GType(ti) => defs += ctypedef_to_rs(&mut ctx, copy ti.name, ti.ty),
            GCompDecl(ci) => {
                ci.name = unnamed_name(&mut ctx, copy ci.name);
                if ci.cstruct {
                    defs += ctypedef_to_rs(&mut ctx, struct_name(copy ci.name), @mut TVoid)
                } else {
                    defs += ctypedef_to_rs(&mut ctx, union_name(copy ci.name), @mut TVoid)
                }
            },
            GComp(ci) => {
                ci.name = unnamed_name(&mut ctx, copy ci.name);
                if ci.cstruct {
                    defs.push(cstruct_to_rs(&mut ctx, struct_name(copy ci.name),
                                            copy ci.fields))
                } else {
                    defs += cunion_to_rs(&mut ctx, union_name(copy ci.name),
                                         copy ci.fields)
                }
            },
            GEnumDecl(ei) => {
                ei.name = unnamed_name(&mut ctx, copy ei.name);
                defs += ctypedef_to_rs(&mut ctx, enum_name(copy ei.name), @mut TVoid)
            },
            GEnum(ei) => {
                ei.name = unnamed_name(&mut ctx, copy ei.name);
                defs += cenum_to_rs(&mut ctx, enum_name(copy ei.name), copy ei.items,
                                    ei.kind)
            },
            _ => { }
        }
    }

    let vars = do vs.map |v| {
        match *v {
            GVar(vi) => cvar_to_rs(&mut ctx, copy vi.name, vi.ty),
            _ => { fail!(~"generate global variables") }
        }
    };

    let funcs = do fs.map |f| {
        match *f {
            GFunc(vi) => {
                match *vi.ty {
                    TFunc(rty, copy aty, var) => cfunc_to_rs(&mut ctx, copy vi.name,
                                                             rty, aty, var),
                    _ => { fail!(~"generate functions") }
                }
            },
            _ => { fail!(~"generate functions") }
        }
    };

    let views = ~[mk_import(&mut ctx, &[~"core", ~"libc"])];
    defs.push(mk_extern(&mut ctx, link, vars, funcs));

    let crate = @dummy_spanned(ast::crate_ {
        module: ast::_mod {
            view_items: views,
            items: defs,
        },
        attrs: ~[],
        config: ~[]
    });

    let ps = pprust::rust_printer(out, ctx.ext_cx.parse_sess().interner);
    out.write_line(~"/* automatically generated by rust-bindgen */\n");
    pprust::print_crate_(ps, crate);
}

fn mk_import(ctx: &mut GenCtx, path: &[~str]) -> @ast::view_item {
    let view = ast::view_item_use(~[
        @dummy_spanned(
            ast::view_path_glob(
                @ast::path {
                   span: dummy_sp(),
                   global: false,
                   idents: path.map(|p| ctx.ext_cx.ident_of(copy *p)),
                   rp: None,
                   types: ~[]
                },
                ctx.ext_cx.next_id()
            )
        )
    ]);

    return @ast::view_item {
              node: view,
              attrs: ~[],
              vis: ast::inherited,
              span: dummy_sp()
           };
}

fn mk_extern(ctx: &mut GenCtx, link: &Option<~str>,
                           vars: ~[@ast::foreign_item],
                           funcs: ~[@ast::foreign_item]) -> @ast::item {
    let attrs;
    match *link {
        None => attrs = ~[],
        Some(ref l) => {
            let link_args = dummy_spanned(ast::attribute_ {
                style: ast::attr_outer,
                value: @dummy_spanned(
                    ast::meta_name_value(
                        @~"link_args",
                        dummy_spanned(ast::lit_str(@(~"-l" + *l)))
                    )
                ),
                is_sugared_doc: false
            });
            attrs = ~[link_args];
        }
    }

    let ext = ast::item_foreign_mod(ast::foreign_mod {
        sort: ast::anonymous,
        abis: abi::AbiSet::from(abi::C),
        view_items: ~[],
        items: vars + funcs
    });

    return @ast::item {
              ident: ctx.ext_cx.ident_of(~""),
              attrs: attrs,
              id: ctx.ext_cx.next_id(),
              node: ext,
              vis: ast::public,
              span: dummy_sp()
           };
}

fn remove_redundent_decl(gs: &[Global]) -> ~[Global] {
    let typedefs = do gs.filtered |g| {
        match(*g) {
            GType(_) => true,
            _ => false
        }
    };

    return do gs.filtered |g| {
        !do typedefs.any |t| {
            match (*g, *t) {
                (GComp(ci1), GType(ti)) => match *ti.ty {
                    TComp(ci2) => {
                        let n = copy ci1.name;
                        ptr::ref_eq(ci1, ci2) && n.is_empty()
                    },
                    _ => false
                },
                (GEnum(ei1), GType(ti)) => match *ti.ty {
                    TEnum(ei2) => {
                        let n = copy ei1.name;
                        ptr::ref_eq(ei1, ei2) && n.is_empty()
                    },
                    _ => false
                },
                _ => false
            }
        }
    };
}

fn ctypedef_to_rs(ctx: &mut GenCtx, name: ~str, ty: @mut Type) -> ~[@ast::item] {
    fn mk_item(ctx: &mut GenCtx, name: ~str, ty: @mut Type) -> @ast::item {
        let rust_name = rust_id(ctx, name).first();
        let rust_ty = cty_to_rs(ctx, ty);
        let base = ast::item_ty(
            @ast::Ty {
                id: ctx.ext_cx.next_id(),
                node: copy rust_ty.node,
                span: dummy_sp(),
            },
            empty_generics()
        );

        return @ast::item {
                  ident: ctx.ext_cx.ident_of(rust_name),
                  attrs: ~[],
                  id: ctx.ext_cx.next_id(),
                  node: base,
                  vis: ast::public,
                  span: dummy_sp()
               };
    }

    return match *ty {
        TComp(ci) => {
            let n = copy ci.name;
            if n.is_empty() {
                ci.name = copy name;
                if ci.cstruct {
                    ~[cstruct_to_rs(ctx, name, copy ci.fields)]
                } else {
                    cunion_to_rs(ctx, name, copy ci.fields)
                }
            } else {
                ~[mk_item(ctx, name, ty)]
            }
        },
        TEnum(ei) => {
            let n = copy ei.name;
            if n.is_empty() {
                ei.name = copy name;
                cenum_to_rs(ctx, name, copy ei.items, ei.kind)
            } else {
                ~[mk_item(ctx, name, ty)]
            }
        },
        _ => ~[mk_item(ctx, name, ty)]
    }
}

fn cstruct_to_rs(ctx: &mut GenCtx, name: ~str, fields: ~[@mut FieldInfo]) -> @ast::item {
    let mut unnamed = 0;
    let fs = do fields.map |f| {
        let n = copy f.name;
        let f_name = if n.is_empty() {
            unnamed += 1;
            fmt!("unnamed_field%u", unnamed)
        } else {
            rust_id(ctx, copy f.name).first()
        };

        let f_ty = cty_to_rs(ctx, f.ty);

        @dummy_spanned(ast::struct_field_ {
            kind: ast::named_field(
                ctx.ext_cx.ident_of(f_name),
                ast::struct_immutable,
                ast::public
            ),
            id: ctx.ext_cx.next_id(),
            ty: f_ty
        })
    };

    let def = ast::item_struct(
        @ast::struct_def {
           fields: fs,
           dtor: None,
           ctor_id: None
        },
        empty_generics()
    );

    return @ast::item { ident: ctx.ext_cx.ident_of(rust_id(ctx, name).first()),
              attrs: ~[],
              id: ctx.ext_cx.next_id(),
              node: def,
              vis: ast::public,
              span: dummy_sp()
           };
}

fn cunion_to_rs(ctx: &mut GenCtx, name: ~str, fields: ~[@mut FieldInfo]) -> ~[@ast::item] {
    fn mk_item(ctx: &mut GenCtx, name: ~str, item: ast::item_) -> @ast::item {
        return @ast::item {
                  ident: ctx.ext_cx.ident_of(name),
                  attrs: ~[],
                  id: ctx.ext_cx.next_id(),
                  node: item,
                  vis: ast::public,
                  span: dummy_sp()
               };
    }

    let ext_cx = ctx.ext_cx;
    let ci = mk_compinfo(copy name, false);
    ci.fields = copy fields;
    let union = @mut TNamed(mk_typeinfo(copy name, @mut TComp(ci)));

    let data = @dummy_spanned(ast::struct_field_ {
        kind: ast::named_field(
            ext_cx.ident_of(~"data"),
            ast::struct_immutable,
            ast::public
        ),
        id: ext_cx.next_id(),
        ty: cty_to_rs(ctx, @mut TArray(@mut TInt(IUChar), type_size(union)))
    });

    let def = ast::item_struct(
        @ast::struct_def {
           fields: ~[data],
           dtor: None,
           ctor_id: None
        },
        empty_generics()
    );
    let union_id = rust_id(ctx, name).first();
    let union_def = mk_item(ctx, union_id, def);

    let expr = quote_expr!(
        unsafe { cast::reinterpret_cast(&ptr::to_unsafe_ptr(self)) }
    );
    let mut unnamed = 0;
    let fs = do fields.map |f| {
        let n = copy f.name;
        let f_name = if n.is_empty() {
            unnamed += 1;
            fmt!("unnamed_field%u", unnamed)
        } else {
            rust_id(ctx, copy f.name).first()
        };

        let ret_ty = cty_to_rs(ctx, @mut TPtr(f.ty));
        let body = dummy_spanned(ast::blk_ {
            view_items: ~[],
            stmts: ~[],
            expr: Some(expr),
            id: ext_cx.next_id(),
            rules: ast::default_blk
        });

        @ast::method {
            ident: ext_cx.ident_of(f_name),
            attrs: ~[],
            generics: empty_generics(),
            self_ty: dummy_spanned(ast::sty_region(None, ast::m_imm)),
            purity: ast::impure_fn,
            decl: ast::fn_decl {
                inputs: ~[],
                output: ret_ty,
                cf: ast::return_val
            },
            body: body,
            id: ext_cx.next_id(),
            span: dummy_sp(),
            self_id: union_def.id,
            vis: ast::public
        }
    };

    let methods = ast::item_impl(
        empty_generics(),
        None,
        cty_to_rs(ctx, union),
        fs
    );

    return ~[
        union_def,
        mk_item(ctx, ~"", methods)
    ];
}

fn cenum_to_rs(ctx: &mut GenCtx, name: ~str, items: ~[@mut EnumItem], kind: IKind) -> ~[@ast::item] {
    let ty = @mut TInt(kind);
    let ty_id = rust_id(ctx, name).first();
    let ty_def = ctypedef_to_rs(ctx, ty_id, ty);
    let val_ty = cty_to_rs(ctx, ty);
    let mut def = ty_def;

    for items.each |it| {
        let cst = ast::item_const(
            val_ty,
            build::mk_int(ctx.ext_cx, dummy_sp(), it.val)
        );

        let val_def = @ast::item {
                         ident: ctx.ext_cx.ident_of(rust_id(ctx, copy it.name).first()),
                         attrs: ~[],
                         id: ctx.ext_cx.next_id(),
                         node: cst,
                         vis: ast::public,
                         span: dummy_sp()
                      };

        def.push(val_def);
    }

    return def;
}

fn mk_link_name_attr(name: ~str) -> ast::attribute {
    let lit = dummy_spanned(ast::lit_str(@name));
    let attr_val = @dummy_spanned(ast::meta_name_value(@~"link_name", lit));
    let attr = ast::attribute_ {
        style: ast::attr_outer,
        value: attr_val,
        is_sugared_doc: false
    };
    dummy_spanned(attr)
}

fn cvar_to_rs(ctx: &mut GenCtx, name: ~str, ty: @mut Type) -> @ast::foreign_item {
    let (rust_name, was_mangled) = rust_id(ctx, copy name);

    let mut attrs = ~[];
    if was_mangled {
        attrs.push(mk_link_name_attr(name));
    }

    return @ast::foreign_item {
              ident: ctx.ext_cx.ident_of(rust_name),
              attrs: attrs,
              node: ast::foreign_item_const(cty_to_rs(ctx, ty)),
              id: ctx.ext_cx.next_id(),
              span: dummy_sp(),
              vis: ast::public,
           };
}

fn cfunc_to_rs(ctx: &mut GenCtx, name: ~str, rty: @mut Type,
                                         aty: ~[(~str, @mut Type)],
                                         _var: bool) -> @ast::foreign_item {
    let ret = match *rty {
        TVoid => @ast::Ty {
            id: ctx.ext_cx.next_id(),
            node: ast::ty_nil,
            span: dummy_sp()
        },
        _ => cty_to_rs(ctx, rty)
    };

    let mut unnamed = 0;
    let args = do aty.map |arg| {
        let (n, t) = copy *arg;

        let arg_name = if n.is_empty() {
            unnamed += 1;
            fmt!("arg%u", unnamed)
        } else {
            rust_id(ctx, n).first()
        };

        let arg_ty = cty_to_rs(ctx, t);

        ast::arg {
            mode: ast::expl(ast::by_copy),
            is_mutbl: false,
            ty: arg_ty,
            pat: @ast::pat {
                 id: ctx.ext_cx.next_id(),
                 node: ast::pat_ident(
                     ast::bind_by_copy,
                     @ast::path {
                         span: dummy_sp(),
                         global: false,
                         idents: ~[ctx.ext_cx.ident_of(arg_name)],
                         rp: None,
                         types: ~[]
                     },
                     None
                 ),
                 span: dummy_sp()
            },
            id: ctx.ext_cx.next_id()
        }
    };

    let decl = ast::foreign_item_fn(
        ast::fn_decl {
            inputs: args,
            output: ret,
            cf: ast::return_val
        },
        ast::impure_fn,
        empty_generics()
    );

    let (rust_name, was_mangled) = rust_id(ctx, copy name);

    let mut attrs = ~[];
    if was_mangled {
        attrs.push(mk_link_name_attr(name));
    }

    return @ast::foreign_item {
              ident: ctx.ext_cx.ident_of(rust_name),
              attrs: attrs,
              node: decl,
              id: ctx.ext_cx.next_id(),
              span: dummy_sp(),
              vis: ast::public,
           };
}

fn cty_to_rs(ctx: &mut GenCtx, ty: @mut Type) -> @ast::Ty {
    return match *ty {
        TVoid => mk_ty(ctx, ~"c_void"),
        TInt(i) => match i {
            IBool => mk_ty(ctx, ~"c_int"),
            ISChar => mk_ty(ctx, ~"c_schar"),
            IUChar => mk_ty(ctx, ~"c_uchar"),
            IInt => mk_ty(ctx, ~"c_int"),
            IUInt => mk_ty(ctx, ~"c_uint"),
            IShort => mk_ty(ctx, ~"c_short"),
            IUShort => mk_ty(ctx, ~"c_ushort"),
            ILong => mk_ty(ctx, ~"c_long"),
            IULong => mk_ty(ctx, ~"c_ulong"),
            ILongLong => mk_ty(ctx, ~"c_longlong"),
            IULongLong => mk_ty(ctx, ~"c_ulonglong")
        },
        TFloat(f) => match f {
            FFloat => mk_ty(ctx, ~"c_float"),
            FDouble => mk_ty(ctx, ~"c_double")
        },
        TPtr(t) => {
            let id = cty_to_rs(ctx, t);
            mk_ptrty(ctx, id)
        },
        TArray(t, s) => {
            let ty = cty_to_rs(ctx, t);
            mk_arrty(ctx, ty, s)
        },
        TFunc(_, _, _) => mk_fnty(ctx),
        TNamed(ti) => {
            let id = rust_id(ctx, copy ti.name).first();
            mk_ty(ctx, id)
        },
        TComp(ci) => {
            ci.name = unnamed_name(ctx, copy ci.name);
            if ci.cstruct {
                mk_ty(ctx, struct_name(copy ci.name))
            } else {
                mk_ty(ctx, union_name(copy ci.name))
            }
        },
        TEnum(ei) => {
            ei.name = unnamed_name(ctx, copy ei.name);
            mk_ty(ctx, enum_name(copy ei.name))
        }
    };
}

fn mk_ty(ctx: &mut GenCtx, name: ~str) -> @ast::Ty {
    let ty = ast::ty_path(
        @ast::path {
            span: dummy_sp(),
            global: false,
            idents: ~[ctx.ext_cx.ident_of(name)],
            rp: None,
            types: ~[]
        },
        ctx.ext_cx.next_id()
    );

    return @ast::Ty {
        id: ctx.ext_cx.next_id(),
        node: ty,
        span: dummy_sp()
    };
}

fn mk_ptrty(ctx: &mut GenCtx, base: @ast::Ty) -> @ast::Ty {
    let ty = ast::ty_ptr(ast::mt{
        ty: base,
        mutbl: ast::m_imm
    });

    return @ast::Ty {
        id: ctx.ext_cx.next_id(),
        node: ty,
        span: dummy_sp()
    };
}

fn mk_arrty(ctx: &mut GenCtx, base: @ast::Ty, n: uint) -> @ast::Ty {
    let sz = ast::expr_lit(@dummy_spanned(ast::lit_uint(n as u64, ast::ty_u)));
    let ty = ast::ty_fixed_length_vec(
        ast::mt {
            ty: base,
            mutbl: ast::m_imm
        },
        @ast::expr {
            id: ctx.ext_cx.next_id(),
            callee_id: ctx.ext_cx.next_id(),
            node: sz,
            span: dummy_sp()
        }
    );

    return @ast::Ty {
        id: ctx.ext_cx.next_id(),
        node: ty,
        span: dummy_sp()
    };
}

fn mk_fnty(ctx: &mut GenCtx) -> @ast::Ty {
    let ty = mk_ty(ctx, ~"u8");
    let @ast::Ty{node: node, _} = mk_ptrty(ctx, ty);

    return @ast::Ty {
        id: ctx.ext_cx.next_id(),
        node: node,
        span: dummy_sp()
    };
}
