#!/usr/bin/env python
# -*- python -*-

import os
import sys
import optparse
import readline
import getpass
import socket
import subprocess
import fabric.network
from fabric.api import env, execute

import ids.fabfile

if __name__ == '__main__':

    parser = optparse.OptionParser()
    parser.add_option('--irodszone', '--zonename', dest='irods_zone',
                      help="name of the new zone")
    parser.add_option('--icathost', dest='icat_host',
                      help="FQDN of the zone's ICAT host")
    parser.add_option('--irodshost', dest='irods_host',
                      help="FQDN of the host that will be the new data server (default is this host)")
    parser.add_option('--irodsuser', '--user', dest='irods_user',
                      help="username of the iRODS administrative user")
    parser.add_option('--irodspassword', '--pass', dest='irods_pass',
                      help="password for the iRODS administrative user")

    parser.add_option('--storagepath', '--vaultpath', dest='vault_path',
                      help="path (relative to data server) where iRODS files should be stored")
    parser.add_option('--resourcename', dest='resc_name',
                      help="name for the storage resource in the zone")

    parser.add_option('--fabuser', dest='fabuser',
                      help="user to connect to remote machine as. Default is calling user.")
    parser.add_option('--no-prompt', action='store_false', dest="prompt", default=True,
                      help="don't prompt for parameter values not provided via command-line options")
    options, args = parser.parse_args()


    # if prompting is turned off, exit if required options (i.e. those without
    # a reasonable default) are not provided
    if not options.prompt:
        if (not options.irods_zone or not options.icat_host
            or not options.irods_user or not options.irods_pass):
            print('You must provide values for zone, ICAT host and iRODS admin username and password')
            sys.exit(1)


    # check provided options, and prompt for those that are missing (and don't have defaults)
    while not options.irods_zone:
        options.irods_zone = raw_input('Enter the name of the iRODS zone: ')
        if not options.irods_zone:
            print('You must provide an iRODS zone name. There is no default.')

    while not options.icat_host:
        options.icat_host = raw_input('Enter the name of the ICAT server for zone %s: '
                                      % (options.irods_zone,))
        if not options.icat_host:
            print('You must provide the ICAT server name. There is no default.')

    if not options.irods_host:
        default_irods_host = socket.getfqdn()
        options.irods_host = raw_input('Enter the name of the new iRODS data server [%s]: '
                                       % (default_irods_host,))
        
    while not options.irods_user:
        options.irods_user = raw_input('Enter the user name for the iRODS administrative user: ')
        if not options.irods_user:
            print('You must provide the iRODS admin user name. There is no default.')

    while not options.irods_pass:
        tmp_pass1 = getpass.getpass('Enter the password for the iRODS administrative user: ')
        if not tmp_pass1:
            print('You cannot use an empty password.')
        tmp_pass2 = getpass.getpass('Enter the password again for verification           : ')
        if tmp_pass1 != tmp_pass2:
            print("Passwords don't match. Try again.")
        else:
            options.irods_pass = tmp_pass1


    # resolve 'localhost' to a FQDN
    if options.irods_host == 'localhost':
        options.irods_host = socket.getfqdn()


    # validity check vault_path and resc_name ... need both or neither
    if options.prompt:
        if not options.vault_path:
            options.vault_path = raw_input('Enter a directory where iRODS will store data on %s: '
                                           % (options.irods_host,))
        if options.vault_path and not options.resc_name:
            options.resc_name = raw_input('Enter the name for the new storage resource at %s: '
                                          % (options.vault_path,))

    if ((options.vault_path and not options.resc_name)
        or (options.resc_name and not options.vault_path)):
        print('Both --storagepath and --resourcename must be provided.')
        sys.exit(1)
        
    if not options.vault_path:
        print('Warning: adding data server without any defined storage location.')
        

    # set up the fabric environment 
    env.irods_zone = options.irods_zone
    env.icat_host = options.icat_host
    env.irods_host = options.irods_host
    env.irods_user = options.irods_user
    env.irods_pass = options.irods_pass
    if options.fabuser:
        env.user = options.fabuser

    env.hosts = [ options.irods_host, ]

    try:
        execute(ids.fabfile.setup_ds)
        if options.vault_path:
            env.vault_path = options.vault_path
            env.resc_name = options.resc_name
            execute(ids.fabfile.manage.add_resource)
    finally:
        fabric.network.disconnect_all()

    sys.exit(0)

    

