#!/usr/bin/env python

import sys

from redis_rpc_client import RedisRPCClient
from config import Config
from tabulate import tabulate


class VOSData(RedisRPCClient):

    def __init__(self):
        config = Config("/etc/vos_cli/vos_cli.conf")
        self.params = config.loadSection("server")
        self.host = self.params["host"]
        self.port = self.params.getint("port")
        self.db = self.params.getint("db")
        self.params = config.loadSection("vos_data")
        self.rpcQueue = self.params["rpc_queue"]
        super(VOSData, self).__init__(self.host, self.port, self.db, self.rpcQueue)

    def help(self):
        sys.exit("""
NAME
       vos_data

SYNOPSYS
       vos_data COMMAND USERNAME

DESCRIPTION
       The purpose of this client application is to notify to the VOSpace backend that
       data is ready to be saved somewhere.

       The client accepts only one (mandatory) command at a time.
       A list of supported commands is shown here below:

       cstore
              performs a 'cold storage' request, data will be saved on tape

       hstore
              performs a 'hot storage' request, data will be saved to disk

       The client also needs to know the username associated to a storage request process.
       The username must be the same used for accessing the transfer node.
    """)

    def store(self, cmd, username):
        request_type = cmd.upper()
        storeRequest = { "requestType": request_type, "userName": username }
        print(f"\nSending {request_type} request...\n")
        storeResponse = self.call(storeRequest)
        if "responseType" not in storeResponse:
            sys.exit("FATAL: Malformed response, storage acknowledge expected.\n")
        elif storeResponse["responseType"] == "STORE_ACK":
            storageList = storeResponse["storageList"]
            storageType = storageList[0]["storage_type"]
            if not storageList:
                sys.exit("No storage point found. Please add a storage point using the 'vos_storage' command.\n")
            print("Choose one of the following storage locations:")
            print()
            print(tabulate(storageList, headers = "keys", tablefmt = "pretty"))
            print()
            storageIdList = []
            for st in storageList:
                storageIdList.append(st["storage_id"])
            storageId = None
            while not storageId in storageIdList:
                try:
                    storageId = input("Please, insert a storage id: ")
                    storageId = int(storageId)
                except ValueError:
                    print("Input type is not valid!")
                except EOFError:
                    print("\nPlease, use CTRL+C to quit.")
                except KeyboardInterrupt:
                    sys.exit("\nCTRL+C detected. Exiting...")
            print()
            print("!!!!!!!!!!!!!!!!!!!!!!!!!!WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
            print("! If you confirm, all your data on the transfer node will be !")
            print("! available in read-only mode for all the time the storage   !")
            print("! process is running.                                        !")
            print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
            print()
            confirm = None
            while not confirm in ( "yes", "no" ):
                try:
                    confirm = input("Are you sure to proceed? [yes/no]: ")
                except KeyboardInterrupt:
                    sys.exit("\nCTRL+C detected. Exiting...")
                except EOFError:
                    print("\nPlease, use CTRL+C to quit.")
            if confirm == "yes":
                confirmRequest = { "requestType": "STORE_CON", 
                                   "userName": username, 
                                   "storageId": storageId, 
                                   "storageType": storageType }
                confirmResponse = self.call(confirmRequest)
                if "responseType" not in confirmResponse:
                    sys.exit("\nFATAL: Malformed response, storage confirmation expected.\n")
                elif confirmResponse["responseType"] == "STORE_RUN":
                    jobId = confirmResponse["jobId"]
                    print(f"\nJobID: {jobId}")
                    print("Storage process started successfully!\n")
                else:
                    sys.exit("FATAL: Unknown response type.\n")
            else:
                sys.exit("\nStorage process aborted gracefully.\n")
        elif storeResponse["responseType"] == "ERROR":
            errorCode = storeResponse["errorCode"]
            errorMsg = storeResponse["errorMsg"]
            sys.exit(f"Error code: {errorCode}\nError message: {errorMsg}\n")
        else:
            sys.exit("\nFATAL: Unknown response type.\n")


# Create new VOSData object
vosDataCli = VOSData()

# Check the number of input args
if len(sys.argv) == 3:
    script, cmd, username = sys.argv
else:
    vosDataCli.help()

# Check the command passed by the user
if cmd == "cstore" or cmd == "hstore":
    vosDataCli.store(cmd, username)
else:
    vosDataCli.help()
 
