import argparse
import os

from typing import Optional

from bemani.format import IFS


def main() -> None:
    parser = argparse.ArgumentParser(description="A utility to extract IFS files.")
    parser.add_argument(
        "file",
        help="IFS file to extract.",
        type=str,
    )
    parser.add_argument(
        "-d",
        "--directory",
        help="Directory to extract to. Defaults to current directroy.",
        default="."
    )
    parser.add_argument(
        "--convert-xml-files",
        help="Convert xml files that are in binary to readable text.",
        action="store_true",
    )
    parser.add_argument(
        "--convert-texture-files",
        help="Convert texture files that are in game-format to PNG files.",
        action="store_true",
    )
    args = parser.parse_args()

    root = args.directory
    if root[-1] != '/':
        root = root + '/'
    root = os.path.realpath(root)

    fileroot = os.path.dirname(os.path.realpath(args.file))

    def load_ifs(fname: str, root: bool=False) -> Optional[IFS]:
        fname = os.path.join(fileroot, fname)
        if os.path.isfile(fname):
            fp = open(fname, 'rb')
            data = fp.read()
            fp.close()

            return IFS(
                data,
                decode_binxml=root and args.convert_xml_files,
                decode_textures=root and args.convert_texture_files,
                keep_hex_names=not root,
                reference_loader=load_ifs,
            )
        else:
            return None

    ifs = load_ifs(args.file, root=True)
    if ifs is None:
        raise Exception(f"Couldn't locate file {args.file}!")

    for fn in ifs.filenames:
        print(f'Extracting {fn} to disk...')
        realfn = os.path.join(root, fn)
        dirof = os.path.dirname(realfn)
        os.makedirs(dirof, exist_ok=True)
        with open(realfn, 'wb') as fp:
            fp.write(ifs.read_file(fn))


if __name__ == '__main__':
    main()
