use std::hashmap::{HashMap, HashSet};
use std::{io, os, path};

use il = types;
use types::*;
use cx = clang;
use clang::*;
use clang::ll::*;
use gen::*;

struct BindGenCtx {
    match_pat: ~[~str],
    abi: ~str,
    builtins: bool,
    link: Option<~str>,
    out: @io::Writer,
    name: HashMap<Cursor, Global>,
    globals: ~[Global],
    builtin_defs: ~[Cursor],
    builtin_names: HashSet<~str>,
    emit_ast: bool,
    fail_on_bitfield: bool
}

enum ParseResult {
    CmdUsage,
    ParseOk(~[~str], @mut BindGenCtx),
    ParseErr(~str)
}

fn parse_args(args: &[~str]) -> ParseResult {
    let mut clang_args = ~[];
    let args_len = args.len();

    let mut out = io::stdout();
    let mut pat = ~[];
    let mut link = None;
    let mut abi = ~"C";
    let mut builtins = false;
    let mut emit_ast = false;
    let mut fail_on_bitfield = true;

    if args_len == 0u {
        return CmdUsage;
    }

    let mut ix = 0u;
    while ix < args_len {
        match args[ix] {
            ~"--help" | ~"-h" => {
                return CmdUsage;
            }
            ~"-emit-clang-ast" => {
              emit_ast = true;
              ix += 1u;
            }
            ~"-o" => {
                if ix + 1u >= args_len {
                    return ParseErr(~"Missing output filename");
                }
                match io::file_writer(&path::Path(args[ix + 1u]),
                                      [io::Create, io::Truncate]) {
                  Ok(f) => { out = f; }
                  Err(e) => { return ParseErr(e); }
                }
                ix += 2u;
            }
            ~"-l" => {
                if ix + 1u >= args_len {
                    return ParseErr(~"Missing link name");
                }
                link = Some(args[ix + 1u].clone());
                ix += 2u;
            }
            ~"-match" => {
                if ix + 1u >= args_len {
                    return ParseErr(~"Missing match pattern");
                }
                pat.push(args[ix + 1u].clone());
                ix += 2u;
            }
            ~"-builtins" => {
                builtins = true;
                ix += 1u;
            }
            ~"-abi" => {
                abi = args[ix + 1u].clone();
                ix += 2u;
            }
            ~"-allow-bitfields" => {
              fail_on_bitfield = false;
              ix += 1u;
            }
            _ => {
                clang_args.push(args[ix].clone());
                ix += 1u;
            }
        }
    }

    let ctx = @mut BindGenCtx { match_pat: pat,
                                abi: abi,
                                builtins: builtins,
                                link: link,
                                out: out,
                                name: HashMap::new(),
                                globals: ~[],
                                builtin_defs: ~[],
                                builtin_names: builtin_names(),
                                emit_ast: emit_ast,
                                fail_on_bitfield: fail_on_bitfield
                              };

    return ParseOk(clang_args, ctx);
}

fn builtin_names() -> HashSet<~str> {
    let mut names = HashSet::new();
    let keys = ~[
        ~"__va_list_tag"
    ];

    keys.move_iter().advance(|s| {
        names.insert(s);
        true
    });

    return names;
}

fn print_usage(bin: ~str) {
    io::print(fmt!("Usage: %s [options] input.h", bin) +
"
Options:
    -h or --help     Display help message
    -l <name>        Link name of the library
    -o <output.rs>   Write bindings to <output.rs> (default stdout)
    -match <name>    Only output bindings for definitions from files
                     whose name contains <name>
                     If multiple -match options are provided, files
                     matching any rule are bound to.
    -builtins        Output bindings for builtin definitions
                     (for example __builtin_va_list)
    -abi <abi>       Indicate abi of extern functions (default C)
    -allow-bitfields Don't fail if we encounter a bitfield
                     (default is false, since rust does not support bitfields)
    -emit-clang-ast  Output the ast (for debugging purposes)

    Options other than stated above are passed to clang.
"
    );
}

fn match_pattern(ctx: @mut BindGenCtx, cursor: &Cursor) -> bool {
    let (file, _, _, _) = cursor.location().location();

    if file.is_null() {
        return ctx.builtins;
    }

    if ctx.match_pat.is_empty() {
        return true;
    }

    let name = file.name();
    let mut found = false;
    ctx.match_pat.iter().advance(|pat| {
        if name.contains(*pat) {
            found = true;
        }
        true
    });

    return found;
}

fn decl_name(ctx: @mut BindGenCtx, cursor: &Cursor) -> Global {
    let mut new_decl = false;
    let decl = {
        *do ctx.name.find_or_insert_with(*cursor) |_| {
            new_decl = true;
            let spelling = cursor.spelling();
    
            let decl = match cursor.kind() {
              CXCursor_StructDecl => {
                let ci = mk_compinfo(spelling, true, ~[]);
                GCompDecl(ci)
              }
              CXCursor_UnionDecl => {
                let ci = mk_compinfo(spelling, false, ~[]);
                GCompDecl(ci)
              }
              CXCursor_EnumDecl => {
                let kind = if cursor.enum_type().kind() == CXType_Int {
                    IInt
                } else {
                    IUInt
                };
                let ei = mk_enuminfo(spelling, kind, ~[]);
                GEnumDecl(ei)
              }
              CXCursor_TypedefDecl => {
                let ti = mk_typeinfo(spelling, @TVoid);
                GType(ti)
              }
              CXCursor_VarDecl => {
                let vi = mk_varinfo(spelling, @TVoid);
                GVar(vi)
              }
              CXCursor_FunctionDecl => {
                let vi = mk_varinfo(spelling, @TVoid);
                GFunc(vi)
              }
              _ => GOther
            };
    
            decl
        }
    };

    if (new_decl) {
        if ctx.builtin_names.contains(&cursor.spelling()) {
            ctx.builtin_defs.push(*cursor);
        }
    }

    return decl;
}

fn opaque_decl(ctx: @mut BindGenCtx, decl: &Cursor) {
    let name = decl_name(ctx, decl);
    ctx.globals.push(name);
}

fn fwd_decl(ctx: @mut BindGenCtx, cursor: &Cursor, f: &fn()) {
    let def = &cursor.definition();
    if cursor == def {
        f();
    } else if def.kind() == CXCursor_NoDeclFound ||
              def.kind() == CXCursor_InvalidFile {
        opaque_decl(ctx, cursor);
    }
}

fn conv_ptr_ty(ctx: @mut BindGenCtx, ty: &cx::Type, cursor: &Cursor) -> @il::Type {
    let is_const = ty.is_const();
    match ty.kind() {
      CXType_Void => {
        return @TPtr(@TVoid, is_const)
      }
      CXType_Unexposed |
      CXType_FunctionProto |
      CXType_FunctionNoProto => {
        let ret_ty = ty.ret_type();
        let decl = ty.declaration();
        return if ret_ty.kind() != CXType_Invalid {
            let args_lst = do ty.arg_types().map |arg| {
                (~"", conv_ty(ctx, arg, cursor))
            };
            let ret_ty = conv_ty(ctx, &ret_ty, cursor);

            @TFunc(ret_ty, args_lst, ty.is_variadic())
        } else if decl.kind() != CXCursor_NoDeclFound {
            @TPtr(conv_decl_ty(ctx, &decl), is_const)
        } else {
            @TPtr(@TVoid, is_const)
        };
      }
      CXType_Typedef => {
        let decl = ty.declaration();
        let def_ty = decl.typedef_type();
        if def_ty.kind() == CXType_FunctionProto ||
           def_ty.kind() == CXType_FunctionNoProto {
            return @TPtr(conv_ptr_ty(ctx, &def_ty, cursor), is_const);
        } else {
            return @TPtr(conv_ty(ctx, ty, cursor), is_const);
        }
      }
      _ => return @TPtr(conv_ty(ctx, ty, cursor), is_const),
    }
}

fn conv_decl_ty(ctx: @mut BindGenCtx, cursor: &Cursor) -> @il::Type {
    return match cursor.kind() {
      CXCursor_StructDecl => {
        let decl = decl_name(ctx, cursor);
        let ci = global_compinfo(decl);
        @TComp(ci)
      }
      CXCursor_UnionDecl => {
        let decl = decl_name(ctx, cursor);
        let ci = global_compinfo(decl);
        @TComp(ci)
      }
      CXCursor_EnumDecl => {
        let decl = decl_name(ctx, cursor);
        let ei = global_enuminfo(decl);
        @TEnum(ei)
      }
      CXCursor_TypedefDecl => {
        let decl = decl_name(ctx, cursor);
        let ti = global_typeinfo(decl);
        @TNamed(ti)
      }
      _ => @TVoid
    };
}

fn conv_ty(ctx: @mut BindGenCtx, ty: &cx::Type, cursor: &Cursor) -> @il::Type {
    return match ty.kind() {
      CXType_Bool => @TInt(IBool),
      CXType_SChar |
      CXType_Char_S => @TInt(ISChar),
      CXType_UChar |
      CXType_Char_U => @TInt(IUChar),
      CXType_UShort => @TInt(IUShort),
      CXType_UInt => @TInt(IUInt),
      CXType_ULong => @TInt(IULong),
      CXType_ULongLong => @TInt(IULongLong),
      CXType_Short => @TInt(IShort),
      CXType_Int => @TInt(IInt),
      CXType_Long => @TInt(ILong),
      CXType_LongLong => @TInt(ILongLong),
      CXType_Float => @TFloat(FFloat),
      CXType_Double => @TFloat(FDouble),
      CXType_LongDouble => @TFloat(FDouble),
      CXType_Pointer => conv_ptr_ty(ctx, &ty.pointee_type(), cursor),
      CXType_Record |
      CXType_Typedef  |
      CXType_Unexposed |
      CXType_Enum => conv_decl_ty(ctx, &ty.declaration()),
      CXType_ConstantArray => @TArray(conv_ty(ctx, &ty.elem_type(), cursor), ty.array_size()),
      _ => @TVoid
    };
}

fn opaque_ty(ctx: @mut BindGenCtx, ty: &cx::Type) {
    if ty.kind() == CXType_Record || ty.kind() == CXType_Enum {
        let decl = ty.declaration();
        let def = decl.definition();
        if def.kind() == CXCursor_NoDeclFound ||
           def.kind() == CXCursor_InvalidFile {
            opaque_decl(ctx, &decl);
        }
    }
}

fn visit_struct(cursor: &Cursor,
                parent: &Cursor,
                ctx: @mut BindGenCtx,
                fields: &mut ~[@FieldInfo]) -> Enum_CXVisitorResult {
    if cursor.kind() == CXCursor_FieldDecl {
        let ty = conv_ty(ctx, &cursor.cur_type(), cursor);
        let name = cursor.spelling();
        let bit = cursor.bit_width();
        // If we encounter a bitfield, and fail_on_bitfield is set, throw an
        // error and exit entirely.
        if (bit != None && ctx.fail_on_bitfield) {
            fail!("Cannot handle bitfield `%s` in struct `%s`",
                  name, parent.spelling());
        }
        let field = mk_fieldinfo(name, ty, bit);
        fields.push(field);
    }
    return CXChildVisit_Continue;
}

fn visit_union(cursor: &Cursor,
               ctx: @mut BindGenCtx,
               fields: &mut ~[@FieldInfo]) -> Enum_CXVisitorResult {
    if cursor.kind() == CXCursor_FieldDecl {
        let ty = conv_ty(ctx, &cursor.cur_type(), cursor);
        let name = cursor.spelling();
        let field = mk_fieldinfo(name, ty, None);
        fields.push(field);
    }
    return CXChildVisit_Continue;
}

fn visit_enum(cursor: &Cursor,
              items: &mut ~[@EnumItem]) -> Enum_CXVisitorResult {
    if cursor.kind() == CXCursor_EnumConstantDecl {
        let name = cursor.spelling();
        let val = cursor.enum_val();
        let item = mk_enumitem(name, val);
        items.push(item);
    }
    return CXChildVisit_Continue;
}

fn visit_top<'r>(cur: &'r Cursor,
                 parent: &'r Cursor,
                 ctx: @mut BindGenCtx) -> Enum_CXVisitorResult {
    let cursor = if ctx.builtin_names.contains(&parent.spelling()) {
        parent
    } else {
        cur
    };

    if !match_pattern(ctx, cursor) {
        return CXChildVisit_Continue;
    }

    match cursor.kind() {
      CXCursor_StructDecl => {
        do fwd_decl(ctx, cursor) || {
            let decl = decl_name(ctx, cursor);
            let ci = global_compinfo(decl);
            cursor.visit(|c, p| visit_struct(c, p, ctx, &mut ci.fields));
            ctx.globals.push(GComp(ci));
        }
        return if cur.kind() == CXCursor_FieldDecl {
            CXChildVisit_Break
        } else {
            CXChildVisit_Recurse
        };
      }
      CXCursor_UnionDecl => {
        do fwd_decl(ctx, cursor) || {
            let decl = decl_name(ctx, cursor);
            let ci = global_compinfo(decl);
            cursor.visit(|c, _| visit_union(c, ctx, &mut ci.fields));
            ctx.globals.push(GComp(ci));
        }
        return CXChildVisit_Recurse;
      }
      CXCursor_EnumDecl => {
        do fwd_decl(ctx, cursor) || {
            let decl = decl_name(ctx, cursor);
            let ei = global_enuminfo(decl);
            cursor.visit(|c, _| visit_enum(c, &mut ei.items));
            ctx.globals.push(GEnum(ei));
        }
        return CXChildVisit_Continue;
      }
      CXCursor_FunctionDecl => {
        let linkage = cursor.linkage();
        if linkage != CXLinkage_External && linkage != CXLinkage_UniqueExternal {
            return CXChildVisit_Continue;
        }

        let args_lst = do cursor.args().map |arg| {
            let arg_name = arg.spelling();
            (arg_name, conv_ty(ctx, &arg.cur_type(), cursor))
        };

        let ty = cursor.cur_type();
        let ret_ty = conv_ty(ctx, &cursor.ret_type(), cursor);

        let func = decl_name(ctx, cursor);
        global_varinfo(func).ty = @TFunc(ret_ty, args_lst, ty.is_variadic());
        ctx.globals.push(func);

        return CXChildVisit_Continue;
      }
      CXCursor_VarDecl => {
        let linkage = cursor.linkage();
        if linkage != CXLinkage_External && linkage != CXLinkage_UniqueExternal {
            return CXChildVisit_Continue;
        }

        let ty = conv_ty(ctx, &cursor.cur_type(), cursor);
        let var = decl_name(ctx, cursor);
        global_varinfo(var).ty = ty;
        global_varinfo(var).is_const = cursor.cur_type().is_const();
        ctx.globals.push(var);

        return CXChildVisit_Continue;
      }
      CXCursor_TypedefDecl => {
        let mut under_ty = cursor.typedef_type();
        if under_ty.kind() == CXType_Unexposed {
            under_ty = under_ty.canonical_type();
        }

        let ty = conv_ty(ctx, &under_ty, cursor);
        let typedef = decl_name(ctx, cursor);
        global_typeinfo(typedef).ty = ty;
        ctx.globals.push(typedef);

        opaque_ty(ctx, &under_ty);

        return CXChildVisit_Continue;
      }
      CXCursor_FieldDecl => {
        return CXChildVisit_Continue;
      }
      _ => return CXChildVisit_Recurse,
    }
}

#[main]
fn main() {
    let mut bind_args = os::args();
    let bin = bind_args.shift();

    match parse_args(bind_args) {
        ParseErr(e) => fail!(e),
        CmdUsage => print_usage(bin),
        ParseOk(clang_args, ctx) => {
            let ix = cx::Index::create(false, true);
            if ix.is_null() {
                fail!(~"clang failed to create index");
            }

            let unit = TranslationUnit::parse(&ix, "", clang_args, [], 0);
            if unit.is_null() {
                fail!(~"No input files given");
            }

            let mut c_err = false;
            let diags = unit.diags();
            diags.iter().advance(|d| {
                io::stderr().write_line(d.format(Diagnostic::default_opts()));
                if d.severity() >= CXDiagnostic_Error {
                    c_err = true;
                }
                true
            });

            if c_err {
                return;
            }

            let cursor = unit.cursor();

            if ctx.emit_ast {
                cursor.visit(|cur, _| ast_dump(cur, 0));
            }			

            cursor.visit(|cur, parent| visit_top(cur, parent, ctx));
                
            while !ctx.builtin_defs.is_empty() {
                let c = ctx.builtin_defs.shift();
                c.visit(|cur, parent| visit_top(cur, parent, ctx));
            }

            gen_rs(ctx.out, ctx.abi.clone(), &ctx.link, ctx.globals);

            unit.dispose();
            ix.dispose();
        }
    }
}
