#!/usr/bin/env python
# -*- coding: utf-8 -*-
# vim:set ts=4 sw=4 et:
#
# Copyright 2014 Vladimir Ermakov.
#
# This file is part of the mavros package and subject to the license terms
# in the top-level LICENSE file of the mavros repository.
# https://github.com/mavlink/mavros/tree/master/LICENSE.md

from __future__ import print_function

import argparse

import os
import rospy
import mavros
from mavros.utils import *
from mavros.nuttx_crc32 import *
from mavros import ftp


def do_list(args):
    for ent in ftp.listdir(args.path):
        n = ent.name
        if ent.type == ftp.FileEntry.TYPE_DIRECTORY:
            n += '/'
        else:
            n += '\t{}'.format(ent.size)

        print(n)


def do_cat(args):
    local_crc = 0

    with ftp.open(args.path, 'r') as fd:
        while True:
            buf = fd.read(1024)
            if len(buf) == 0:
                break

            local_crc = nuttx_crc32(buf, local_crc)
            sys.stdout.write(buf)

    remote_crc = ftp.checksum(args.path)
    if local_crc != remote_crc:
        raise IOError("Verification failed: 0x{local_crc:08x} != 0x{remote_crc:08x}".format(**locals()))


def do_remove(args):
    ftp.unlink(args.path)


def do_reset(args):
    ftp.reset_server()


def do_mkdir(args):
    ftp.mkdir(args.path)


def do_rmdir(args):
    ftp.rmdir(args.path)


def do_upload(args):
    mode = 'cw' if args.no_overwrite else 'w'
    local_crc = 0

    with args.file as from_fd:
        with ftp.open(args.path, mode) as to_fd:
            while True:
                buf = from_fd.read(1024)
                if len(buf) == 0:
                    break

                local_crc = nuttx_crc32(buf, local_crc)
                to_fd.write(buf)

    remote_crc = ftp.checksum(args.path)
    if local_crc != remote_crc:
        raise IOError("Verification failed: 0x{local_crc:08x} != 0x{remote_crc:08x}".format(**locals()))


def main():
    parser = argparse.ArgumentParser(description="File manipulation tool for MAVLink-FTP.")
    parser.add_argument('-n', '--mavros-ns', help="ROS node namespace", default="/mavros")
    parser.add_argument('-v', '--verbose', action='store_true', help="verbose output")
    subarg = parser.add_subparsers()

    list_args = subarg.add_parser('list', help="list files and dirs")
    list_args.set_defaults(func=do_list)
    list_args.add_argument('path', type=str, help="directory path")

    cat_args = subarg.add_parser('cat', help="cat file")
    cat_args.set_defaults(func=do_cat)
    cat_args.add_argument('path', type=str, help="file path")

    remove_args = subarg.add_parser('remove', help="remove file")
    remove_args.set_defaults(func=do_remove)
    remove_args.add_argument('path', type=str, help="file path")

    mkdir_args = subarg.add_parser('mkdir', help="create direcotory")
    mkdir_args.set_defaults(func=do_mkdir)
    # mkdir_args.add_argument('-p', action='store_true', help="dir path")
    mkdir_args.add_argument('path', type=str, help="dir path")

    rmdir_args = subarg.add_parser('rmdir', help="remove directory")
    rmdir_args.set_defaults(func=do_rmdir)
    rmdir_args.add_argument('path', type=str, help="dir path")

    upload_args = subarg.add_parser('upload', help="upload file")
    upload_args.set_defaults(func=do_upload)
    upload_args.add_argument('file', type=argparse.FileType('rb'), help="file to send")
    upload_args.add_argument('path', type=str, help="save path")
    upload_args.add_argument('-n', '--no-overwrite', action="store_true", help="do not overwrite existing file")

    reset_args = subarg.add_parser('reset', help="reset")
    reset_args.set_defaults(func=do_reset)

    args = parser.parse_args(rospy.myargv(argv=sys.argv)[1:])

    rospy.init_node("mavftp", anonymous=True)
    mavros.set_namespace(args.mavros_ns)
    args.func(args)


if __name__ == '__main__':
    main()
