#!/opt/alt/python35/bin/python3.5

import base64
import subprocess
import json
import os
import socket
import select
import shutil
import random
import string
import sys

SOCKET_PATH_ROOT = '/var/run/defence360agent/simple_rpc.sock'
SOCKET_PATH_USER = '/var/run/defence360agent/non_root_simple_rpc.sock'


class ExecuteError(Exception):
    def __str__(self):
        return 'ExecuteError: ' + super(ExecuteError, self).__str__()


def execute(command):
    socket_path = SOCKET_PATH_ROOT if os.getegid() == 0 else SOCKET_PATH_USER

    try:
        with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as sock:
            sock.connect(socket_path)
            sock.sendall(str.encode(command) + b'\n')

            fd_list = [sock.fileno()]
            rwx_list = select.select(fd_list, [], [], 180)

            if sock.fileno() not in rwx_list[0]:
                raise Exception('Request timeout')

            response = sock.makefile(encoding='utf-8').readline()
            if not response:
                raise Exception('Empty response from socket')

            print(response)
    except (ConnectionRefusedError, FileNotFoundError):
        proc = subprocess.Popen(['ps', 'ax'], stdout=subprocess.PIPE)
        is_runs = 'i360deploy.sh' in proc.stdout.read().decode()
        message = 'notifications.serviceIsInstalling'\
            if is_runs else 'notifications.serviceNotStarted'
        print(json.dumps({
            'result': 'error',
            'messages': message
        }))


def upload_file(params):
    params = json.loads(params)
    upload_path = '/var/imunify360/uploads'
    uploaded = []

    for tmp_path, file_name in params.get('files', {}).items():
        file_name = file_name.encode('utf-8')
        path = os.path.join(bytes(upload_path, 'utf-8'), file_name)
        shutil.move(tmp_path.encode('utf-8'), path)
        os.chown(path, 0, 0)
        os.chmod(path, 0o600)
        uploaded.append(path)

    random_name = ''.join(random.choice(string.ascii_uppercase + string.digits)
                          for _ in range(8))
    zip_file = random_name + '.zip'
    zip_path = os.path.join('/var/imunify360/uploads', zip_file)
    subprocess.call(
        ['zip', '-j', '-m', '--password', '1', zip_path] + uploaded,
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT,
        shell=False)
    os.chown(zip_path, 0, 0)
    os.chmod(zip_path, 0o600)

    result = {
        'result': 'success',
        'data': zip_path,
    }

    print(json.dumps(result))


if __name__ == '__main__':
    action = sys.argv[1]
    data = base64.b64decode(sys.argv[2]).decode()
    dispatcher = {
        'execute': execute,
        'uploadFile': upload_file,
    }

    try:
        dispatcher.get(action, execute)(data)
    except Exception as e:
        print(json.dumps({
            'messages': str(e),
            'result': 'error',
        }))
