#!/usr/bin/env python3
import os
import json
import datetime

import fire

from controller import Controller


class HAL(object):
    """
    HAL manages your data science research environment.
    """

    def configure(self):
        """
        Create the config.json file used to run HAL
        """
        hal_dir = os.path.expanduser('~/.hal')
        if not os.path.exists(hal_dir):
            os.mkdir(hal_dir)

        config = {
            'VolumeId': input('Volume ID: '),
            'ImageId': input('Image ID: '),
            'SubnetId': input('Subnet ID: '),
            'Groups': [input('Security group: ')],
            'key_path': input('Key path: '),
            'password': input('Password: '),
            'user_name': input('Username: '),
            'instance_profile_arn': input('Instance profile ARN: ')
        }

        with open(os.path.join(hal_dir, 'config.json'), 'w') as f:
            json.dump(config, f)

    def connect(self):
        """
        Open an ssh connection to the remote instance. Replaces the current
        process with a new shell on the remote.
        """
        Controller().open_connection_to_instance()

    def describe(self):
        """Describes any currently running instances"""
        print(Controller().describe_instances())

    def get(self, local_path, remote_path):
        """Fetch a file from the remote instance via sftp

         Args:
            local_path (str): The path where the fetched file should be saved
            remote_path (str): The path of the file to fetch from the remote machine
        """
        Controller(set_up_ssh=True).get_file(local_path, remote_path)

    def put(self, local_path, remote_path):
        """Send a file to the remote instance via sftp

         Args:
            local_path (str): The path of the file to send on the local machine
            remote_path (str): The path where the file should be saved on the remote machine
        """
        Controller(set_up_ssh=True).send_file(local_path, remote_path)

    def start(self, instance_type, spot_price=None):
        """Create an instance of a specified type.
        Valid options are listed at https://aws.amazon.com/ec2/spot/pricing/

        Args:
            instance_type (str): The type of instance to create.
            spot_price (str), optional: The type of instance to create. Valid options are listed at https://aws.amazon.com/ec2/spot/pricing/

        """
        c = Controller()
        if c.instance:
            raise ValueError(
                'Looks like you already have an instance running!\n'
                'instance_id: ' + c.instance.id
            )

        instance_name = (
            instance_type + '-' + datetime.datetime.now().strftime('%Y-%m-%d')
        )
        instance_id, spot_price = c.create_instance(
            instance_type,
            instance_name=instance_name,
            spot_price=spot_price
        )
        print(f'instance_id:\t{instance_id}\nspot_price:\t£{spot_price}')
        c.set_up_ssh()
        c.attach_volume()
        c.mount_volume()
        c.fix_dns()
        c.send_file(
            local_path=os.path.join(c.hal_dir, './enable_ipywidgets'),
            remote_path='/home/ec2-user/enable_ipywidgets'
        )
        c.start_jupyterlab()
        c.open_connection_to_instance()

    def stop(self):
        """Shut down a running instance"""
        c = Controller()
        instance_id = c.instance.id
        c.terminate_instance()

        print('Successfully shut down instance: ' + instance_id)

    def open(self):
        """Opens the pod bay doors"""
        config = json.load(open(os.path.expanduser('~/.hal/config.json')))
        print(
            f"I'm sorry, {config['user_name'].title()}. "
            "I'm afraid I can't do that."
        )


if __name__ == '__main__':
    fire.Fire(HAL)
