#!/usr/bin/python

# Copy streams between NilmDB servers with wildcards

import nilmtools.filter
import nilmtools.copy_one
import nilmdb.client
import argparse
import fnmatch

def main(argv = None):
    f = nilmtools.filter.Filter()
    # Reuse filter's parser, since it handles most options we need.
    parser = f.setup_parser(description = """\
    Copy all streams matching the given wildcard from one host to another.

    Example: %(prog)s -u http://host1/nilmdb -U http://host2/nilmdb /sharon/*
    """, skip_paths = True)
    parser.add_argument('-n', '--nometa', action='store_true',
                        help="Don't copy or check metadata")
    parser.add_argument("path", action="store", nargs="+",
                        help='Wildcard paths to copy')
    args = parser.parse_args(argv)

    # Verify arguments
    if args.dest_url is None:
        parser.error("must provide both source and destination URL")
    client_src = nilmdb.client.Client(args.url)
    client_dest = nilmdb.client.Client(args.dest_url)
    if client_src.geturl() == client_dest.geturl():
        parser.error("source and destination URL must be different")
    print("Source URL:", client_src.geturl())
    print("  Dest URL:", client_dest.geturl())

    # Find matching streams
    matched = []
    for path in args.path:
        matched.extend([s for s in client_src.stream_list(extended = True)
                        if fnmatch.fnmatch(s[0], path)
                        and s not in matched])

    # Create destination streams if they don't exist
    for stream in matched:
        src = nilmtools.filter.StreamInfo(client_src.geturl(), stream)
        dest = nilmtools.filter.get_stream_info(client_dest, src.path)
        if not dest:
            print("Creating destination stream", src.path)
            client_dest.stream_create(src.path, src.layout)

    # Copy them all by running the "copy" tool as if it were
    # invoked from the command line.
    for stream in matched:
        new_argv = ["--url", client_src.geturl(),
                     "--dest-url", client_dest.geturl() ]
        if args.start:
            new_argv.extend(["--start", "@" + repr(args.start)])
        if args.end:
            new_argv.extend(["--end", "@" + repr(args.end)])
        if args.dry_run:
            new_argv.extend(["--dry-run"])
        if args.nometa:
            new_argv.extend(["--nometa"])
        if args.force_metadata:
            new_argv.extend(["--force-metadata"])
        new_argv.extend([stream[0], stream[0]])
        try:
            nilmtools.copy_one.main(new_argv)
        except SystemExit as e:
            # Ignore SystemExit which could be raised on --dry-run
            if e.code != 0:  # pragma: no cover (shouldn't happen)
                raise

if __name__ == "__main__":
    main()
