#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2015 Nandaja Varma <nvarma@redhat.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#

import argparse
import sys
import os
import time
import shutil
from glusterlib import Global
from glusterlib import PlaybookGen
from glusterlib import CliOps
from collections import OrderedDict


class GlusterDeploy(PlaybookGen, Global):

    '''
    This class makes use of the class PlaybookGen inside glusterlib
    library to create the ansible playbooks and variable files.
    Then calls ansible-playbook command to setup back-end and
    deploy GlusterFS
    '''

    def __init__(self):
        args = self.parse_arguments()
        self.check_ansible_installation()
        self.verbose = args.verbose
        if args.config_file:
            config_file = args.config_file.name
            PlaybookGen(config_file)
            self.deploy_gluster()
        if args.volumeset:
            CliOps(args.volumeset)
            self.deploy_gluster()
        if not args.keep:
            shutil.rmtree(Global.base_dir)
        else:
            print "You can view the generated configuration files "\
                "inside %s" % Global.base_dir

    def check_ansible_installation(self):
        ret = os.system('ansible --version 1>/dev/null 2>/dev/null')
        if ret:
            print "Error: gdeploy requires Ansible to run. \nPlease install " \
                    "Ansible(version >= 1.9.2) to continue."
            self.cleanup_and_quit()

    def parse_arguments(self):
        '''
        This method uses argparser to parse the command line inputs
        to the gdeploy script
        '''
        usage = 'gdeploy [-h] [-v] [-vv] [-c CONFIG_FILE] ' \
            '[-k] [volumeset <hostIP>:<volumename> <key> <value>]'
        parser = argparse.ArgumentParser(usage=usage, version='1.0')
        parser.add_argument('-c', dest='config_file',
                            help="Configuration file",
                            type=argparse.FileType('rt'))
        parser.add_argument('volumeset',
                            help="Set options for the volume",
                            nargs='*')
        parser.add_argument('-k', dest='keep',
                            action='store_true',
                            help="Keep the generated ansible utility files")
        parser.add_argument('-vv', dest='verbose',
                            action='store_true',
                            help="verbose mode")
        try:
            args = parser.parse_args()
        except IOError as msg:
            parser.error(str(msg))
        both_not_present = not (args.config_file or args.volumeset)
        if both_not_present:
            parser.print_help()
            self.cleanup_and_quit()
        return args

    def deploy_gluster(self):
        if Global.playbooks:
            Global.playbooks = self.validate_playbook_order(Global.playbooks)
            self.write_ansible_playbook()
            self.call_ansible_command()

    def validate_playbook_order(self, yml):
        if 'gluster-volume-delete.yml' in yml:
            yml.remove('gluster-volume-delete.yml')
            yml.append('gluster-volume-delete.yml')
        if 'gluster-peer-detach.yml' in yml:
            yml.remove('gluster-peer-detach.yml')
            yml.append('gluster-peer-detach.yml')
        return yml

    def write_ansible_playbook(self):
        playbooks = '---\n- include: ' + '\n- include: '.join(Global.playbooks)
        with open(Global.playbooks_file, 'w') as fd:
            fd.write(playbooks)

    def call_ansible_command(self):
        '''
        Calls the ansible-playbook command on necessary yamls
        '''
        verbose = '-vv' if self.verbose else ''
        try:
            self.exec_ansible_cmd(verbose)
        except:
            print "Error: Looks like there is something wrong with " \
                "your ansible installation."


if __name__ == '__main__':
    GlusterDeploy()
