var fd = use('fd')
var qop = use('qop')

function print_usage() {
    log.console("Usage: qopconv [OPTION...] FILE...")
    log.console("  -u <archive> .. unpack archive")
    log.console("  -l <archive> .. list contents of archive")
    log.console("  -d <dir> ....... change read dir when creating archives")
    log.console("  <sources...> <archive> .. create archive from sources")
}

function list_archive(archive_path) {
    var blob = fd.slurp(archive_path)
    var archive = null
    if (!blob) {
        log.console("Could not open archive " + archive_path)
        return
    }
    var _open = function() {
        archive = qop.open(blob)
    } disruption {
        log.console("Could not open archive " + archive_path)
        return
    }
    _open()

    var files = archive.list()
    arrfor(files, function(f) {
        var s = archive.stat(f)
        // Format: index hash size path
        // We don't have index/hash easily available in JS binding yet, just size/path
        log.console(`${f} (${s.size} bytes)`)
    })
    archive.close()
}

function unpack(archive_path) {
    var blob = fd.slurp(archive_path)
    var archive = null
    if (!blob) {
        log.console("Could not open archive " + archive_path)
        return
    }
    var _open = function() {
        archive = qop.open(blob)
    } disruption {
        log.console("Could not open archive " + archive_path)
        return
    }
    _open()

    var files = archive.list()
    arrfor(files, function(f) {
        var data = archive.read(f)
        var dir = null
        var parts = null
        var curr = null
        var fh = null
        var _mk = null
        if (data) {
            // Ensure directory exists
            dir = fd.dirname(f)
            if (dir) {
                // recursive mkdir
                parts = array(dir, '/')
                curr = "."
                arrfor(parts, function(p) {
                    curr += "/" + p
                    _mk = function() { fd.mkdir(curr) } disruption {}
                    _mk()
                })
            }
            fh = fd.open(f, "w")
            fd.write(fh, data)
            fd.close(fh)
            log.console("Extracted " + f)
        }
    })
    archive.close()
}

function pack(sources, archive_path, read_dir) {
    var writer = qop.write(archive_path)

    var base_dir = read_dir || "."

    function add_recursive(path) {
        var full_path = base_dir + "/" + path
        var st = null
        var list = null
        var data = null
        if (path == ".") full_path = base_dir
        if (read_dir == null && path != ".") full_path = path

        st = fd.stat(full_path)
        if (!st) {
            log.console("Could not stat " + full_path)
            return
        }

        if (st.isDirectory) {
            list = fd.readdir(full_path)
            arrfor(list, function(item) {
                if (item == "." || item == "..") return
                var sub = path == "." ? item : path + "/" + item
                add_recursive(sub)
            })
        } else {
            data = fd.slurp(full_path)
            if (data) {
                writer.add_file(path, data)
                log.console("Added " + path)
            }
        }
    }

    arrfor(sources, function(s) {
        add_recursive(s)
    })

    writer.finalize()
    log.console("Created " + archive_path)
}

var sources = null
var archive = null
var read_dir = null
var i = 0

if (!is_array(args) || length(args) < 1) {
    print_usage()
} else {
    if (args[0] == "-l") {
        if (length(args) < 2) print_usage()
        else list_archive(args[1])
    } else if (args[0] == "-u") {
        if (length(args) < 2) print_usage()
        else unpack(args[1])
    } else {
        sources = []
        archive = null
        read_dir = null
        i = 0
        if (args[0] == "-d") {
            read_dir = args[1]
            i = 2
        }

        for (; i < length(args) - 1; i++) {
            push(sources, args[i])
        }
        archive = args[length(args) - 1]

        if (length(sources) == 0) {
            print_usage()
        } else {
            pack(sources, archive, read_dir)
        }
    }
}

$stop()
