#!/usr/bin/python3
#
# Copyright 2023 ESO (eso.org)
#

from cii.mgmt import redis_raw
from cii.mgmt import config_impex
from cii.mgmt import host_resolve

import sys
import argparse
from urllib.parse import urlparse


def _ask_confirmation (user_message, preview):

  if len (preview)==0:
      print("No matches, nothing to do")
      return False

  listing = "\n ".join(preview[:3])
  if len(preview) > 3:
      listing += f"\n and {len(preview)-3} more ..."

  print(f'{len(preview)} {user_message}:\n {listing}')

  while True:
      ans = input('Is this what you intend [y][N][l]ist ? ')
      if ans == 'l': print (" "+"\n ".join(preview)) ; continue
      if ans == 'y': return True
      return False



def _main():

    default_config_server='localhost:6379'

    default_index_filter = config_impex.PREFIX_USER_CDB

    parser = argparse.ArgumentParser(description = 'Dump config-db to filesystem,'
                                                   ' or reverse-dump it back.')
    parser.add_argument('command', type=str, choices=['dump', 'upload'],
                        help='The command')
    parser.add_argument('--config-server', default=default_config_server,
                        help='Address of redis server where configuration is stored. Default: %(default)s.'
                             ' Legacy format (discouraged): tcp[.single|.cluster]://<HOSTNAME>:<PORT>'
                             ' Note: only localhost or 127.0.0.1 will be accepted as hostname!', metavar='addr')
    parser.add_argument('--fi', default=default_index_filter, type=str, choices=default_index_filter, nargs='*',
                        help='Filter: index shortnames ('+(' '.join(default_index_filter))+')', metavar='idx')
    parser.add_argument('--fn', default='', type=str,
                        help='Filter: partial doc name', metavar='name')
    parser.add_argument('--fv',  action='store_true',
                        help='Filter: latest doc version (on download)')
    parser.add_argument('--fm',  action='store_true',
                        help='Filter: modified since download time (on upload)')
    parser.add_argument('--dp', action='store_true',
                        help='Enables access to datapoints index (if any on config-server)')
    parser.add_argument('--dir', default='.', type=str,
                        help='Directory where to dump/load, default: cwd')
    parser.add_argument('-y', action='store_true',
                        help='Do not show preview and ask no questions')

    args = parser.parse_args()

    # 2024-06: tcp-format discouraged but still supported
    if args.config_server.startswith('tcp://') \
      or args.config_server.startswith('tcp.single://') \
      or args.config_server.startswith('tcp.cluster://'):
      addr = urlparse (args.config_server)
      conf_host = addr.hostname
      conf_port = addr.port
    else:
      conf_host,conf_port = args.config_server.split(':')

    if conf_host != 'localhost' and conf_host != '127.0.0.1':
        print("Error: For disaster prevention, this command can only be run on the config-storage host.")
        print("Allowed hostnames: localhost, 127.0.0.1. You have specified:", conf_host)
        return 1

    client = redis_raw.redis_client(conf_host, conf_port)

    indices = args.fi
    if args.dp: # for oldb-testing also allow to dump datapoints
        indices.extend(config_impex.PREFIX_USER_EXPER)

    if args.command == 'dump':
      if not args.y:
        docs = config_impex.download (client, indices, args.fn, args.dir, args.fv, dry_run=True)
        if not _ask_confirmation(f"docs will be written to the filesystem ({args.dir}/)", docs):
          return
      docs = config_impex.download (client, indices, args.fn, args.dir, args.fv)
      print (f'Downloaded {len(docs)} docs from redis');

    elif args.command == 'upload':
      if not args.y:
        mods = config_impex.upload (client, indices, args.fn, args.dir, args.fm, dry_run=True)
        if not _ask_confirmation("keys (or fields) will be written to redis", mods):
          return
      mods = config_impex.upload (client, indices, args.fn, args.dir, args.fm)
      print (f'Uploaded {len(mods)} docs to redis')

if __name__ == '__main__':
    _main()
