import json
import os
import paramiko
import scp
import sys
import uuid

from tape_task import TapeTask


class TapeClient(object):

    # Constructor
    def __init__(self, host, port, user, keyFile):
        self.host = host
        self.port = port
        self.user = user
        self.client = paramiko.SSHClient()
        self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        self.key = paramiko.RSAKey.from_private_key_file(keyFile)
        self.client.load_system_host_keys()
        self.scp = None
        self.taskList = []
    
    # Connects to the tape library frontend
    def connect(self):
        self.client.connect(hostname = self.host,
                            port = self.port,
                            username = self.user,
                            pkey = self.key)
    
    # Returns the whole task list
    def getTaskList(self):
        stdin, stdout, stderr = self.client.exec_command("eeadm task list --json")
        exitCode = stdout.channel.recv_exit_status()
        if not exitCode:
            result = json.loads(stdout.readlines()[0].rstrip('\n'))
            #print(result)
            #print(len(result["payload"]))
            #print(result["payload"][0])
            for t in result["payload"]:
                task = TapeTask()
                task.inUseTapes = t["inuse_tapes"]
                task.inUsePools = t["inuse_pools"]
                task.inUseNodeGroups = t["inuse_node_groups"]
                task.inUseDrives = t["inuse_drives"]
                task.cmdParam = t["cmd_param"]
                task.result = t["result"]
                task.status = t["status"]
                task.completedTime = t["completed_time"]
                task.startedTime = t["started_time"]
                task.createdTime = t["created_time"]
                task.setInUseLibs = t["inuse_libs"]
                task.type = t["type"]
                task.taskId = t["task_id"]
                task.id = t["id"]
                self.taskList.append(task)
            return self.taskList
        else:
            sys.exit("cmd_exit_code = FAILURE")
            
    # Copies files/dirs recursively by passing their absolute paths        
    def copy(self, srcPath, destPath):
        self.scp = scp.SCPClient(self.client.get_transport())
        print(f"Copying {srcPath} in {destPath}")
        if os.path.isdir(srcPath):
            self.scp.put(srcPath, recursive = True, remote_path = destPath)
        elif os.path.isfile(srcPath):
            self.scp.put(srcPath, destPath)
        else:
            sys.exit("FATAL: invalid file/dir.")
        self.scp.close()    
    
    def recall(self, fileList):
        #TODO        
        tmp = str(uuid.uuid1().hex) + "-vos_recall.tmp"
        fp = open(tmp, "a")
        for f in fileList:
            fp.write(f"{f}\n")
        fp.close()
        self.copy("./" + tmp, "/tmp/" +  tmp)
        cmd = "eeadm recall /tmp/" + tmp
        stdin, stdout, stderr = self.client.exec_command(cmd)
    
    def recallChecksumFiles(self, dirName):
        cmd = "find $(dirname " + dirName + ") -type f \( -iname \"*-md5sum.txt\" \) | /opt/ibm/ltfsee/bin/eeadm recall"
        stdin, stdout, stderr = self.client.exec_command(cmd)
        exitCode = stdout.channel.recv_exit_status()
        out = open("tape_client_log.txt", "a")
        out.write(f"exitCode: {exitCode}\n")
        out.close()
        if exitCode:
            return False
        else:
            return True
    
    # Closes the connection
    def disconnect(self):
        self.client.close()

    def getSize(self, fsMountPoint):
        cmd = "df " + fsMountPoint + " | tail -n +2"
        #out = subprocess.run(cmd, shell = True, capture_output = True)
        stdin, stdout, stderr = self.client.exec_command(cmd)
        #res = stdout.stdout.decode('UTF-8').rstrip('\n')
        res = stdout.readlines()[0]
        res = ' '.join(res.split()).split(' ')
        #print(res)
        total = res[1]
        used = res[2]
        available = res[3]
        return ( total, used, available)
        

# Test
#tc = TapeClient("192.168.56.101", 22, "root", "ibm")
#tc.connect()
#tc.copy("/home/curban/store/mydir", "/home/mydir")
#tc.copy("/home/curban/store/foo2.txt", "/home/mydir/foo2.txt")
#tl = tc.getTaskList()
#fsSize = tc.getSize("/ia2_tape_stb_01")
#print(fsSize)
#tc.disconnect()
#for i in tl:
#    print(i.id)
#    print('\n')