# -*- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
# USA.
#
#
#    yaml_writer.py
#    -------------
#    YamlWriter is a helper class used by VarFileGenerator to write
#    all the necessary sections and options into the yaml file
#    as per specified in the configuration file
#

from gdeploylib import *
from gdeploylib.defaults import *
import sys
import re
try:
    import yaml
except ImportError:
    msg = "Package PyYAML not found."
    print "\nError: " + msg
    Global.logger.error(msg)
    sys.exit(0)
import os


class BackendSetup(Helpers):

    def __init__(self):
        self.section_dict = dict()
        self.previous = True
        self.write_sections()
        Global.hosts = sorted(set(Global.hosts))
        self.remove_from_sections('default')
        self.remove_from_sections('force')
        self.remove_from_sections('gluster')
        self.remove_from_sections('selinux')
        self.remove_from_sections('snapshot-reserve')
        self.remove_from_sections('backend-setup')

    def write_sections(self):
        self.filename = 
 Global.group_file
        backend_setup, hosts = self.check_backend_setup_format()
        default = self.config_get_options('default', Fals
e)
        gluster = self.config_get_options('gluster', False)
        if default:
            self.default = False if default[0].lower() == 'no' else True
        self.default = self.default if hasattr(self, 'default') else True
        if gluster and gluster[0].lower() == 'no':
            self.gluster = False
            self.default = False
        else:
            self.gluster = True
        if not backend_setup:
            self.old_backend_setup()
        else:
            self.new_backend_setup(hosts)

    def call_selinux(self):
        selinux = self.config_get_options('selinux', False)
        Global.logger.info("Setting up SeLinux labels running playbook %s"\
                           %SELINUX_YML)
        if selinux:
            if selinux[0].lower() == 'yes':
                self.run_playbook(SELINUX_YML)


    def new_backend_setup(self, hosts):
        hosts = filter(None, hosts)
        Global.logger.info("Setting up backend on hosts.")
        if hosts:
            Global.var_file = None
            hosts = self.pattern_stripping(hosts)
            for host in hosts:
                self.bricks = []
                Global.current_hosts = [host]
                self.host_file = self.get_file_dir_path(Global.host_vars_dir, host)
                self.touch_file(self.host_file)
                self.parse_section(':' + host)
                self.call_gen_methods()
                self.remove_section(Global.inventory, Global.group)
                self.call_selinux()
        self.section_dict = None
        Global.var_file = None
        self.parse_section('')
        Global.current_hosts = [host for host in Global.hosts if host not in
                hosts]
        if self.section_dict:
            self.filename =  Global.group_file
            self.call_gen_methods()
            self.create_var_files(self.section_dict)
            self.remove_section(Global.inventory, Global.group)
            Global.var_file = 'group_vars'
            self.call_selinux()
        Global.hosts.extend(hosts)
        Global.hosts = sorted(set(Global.hosts))

    def old_backend_setup(self):
        if not self.get_var_file_type():
            return
        else:
            if Global.var_file == 'host_vars':
                for host in Global.hosts:
                    self.current_host = host
                    Global.current_hosts = [host]
                    devices = self.config_section_map(host,
                                              'devices', False)
                    self.filename = self.get_file_dir_path(Global.host_vars_dir, host)
                    self.touch_file(self.filename)
                    self.bricks = self.split_comma_separated_options(devices)
                    self.call_gen_methods()
                    self.call_selinux()
            else:
                Global.current_hosts = Global.hosts
                self.filename =  Global.group_file
                self.call_gen_methods()
                self.create_var_files(self.section_dict)
                self.remove_section(Global.inventory, Global.group)
                self.call_selinux()
            # msg = "This configuration format will be deprecated  "\
            # "in the next release.\nPlease refer the setup guide "\
            # "for the new configuration format."
            # print "Warning: " + msg
            # Global.logger.warning(msg=msg)

    def parse_section(self, hostname):
        try:
            self.section_dict = Global.sections['backend-setup' +
                    hostname]
            del self.section_dict['__name__']
        except KeyError:
            return
        try:
            self.filename = self.host_file
        except:
            self.filename =  Global.group_file
        self.section_dict = self.format_values(self.section_dict)

    def call_gen_methods(self):
        self.perf_spec_data_write()
        self.write_brick_names()
        self.write_vg_names()
        if self.gluster:
            self.write_thinp_names()
        else:
            self.write_lv_names()
        self.write_lvol_names()
        self.write_mount_options()
        self.write_brick_dirs()
        self.create_var_files(self.section_dict)


    def write_brick_names(self):
        self.bricks = self.section_data_gen('devices', 'Devices')
        ssd = filter(None, self.section_data_gen('ssd', "SSD"))
        if ssd:
            self.ssd = self.correct_brick_format(ssd)[0]
            self.section_dict['disk'] = self.ssd
            self.bricks.append(self.ssd)
            Global.logger.info("Setting up SSD bricks")
        if not self.bricks:
            return
        self.bricks = self.correct_brick_format(self.bricks)
        self.device_count = len(self.bricks)
        self.section_dict['bricks'] = self.bricks
        Global.logger.info("Create physical volumes %s - running playbook %s"\
                           %(self.section_dict['bricks'], PVCREATE_YML))
        if self.bricks:
            self.run_playbook(PVCREATE_YML)

    def write_vg_names(self):
        self.vgs = self.section_data_gen('vgs', 'Volume')
        if not self.vgs:
            if not self.bricks:
                return
            self.vgs = self.set_default('vgs')
        self.section_dict['vgs'] = self.vgs
        if self.vgs:
            if not self.bricks:
                self.device_count = len(self.vgs)
                return
        data = []
        if self.device_count != len(self.section_dict['vgs']):
            if self.device_count > 1 and len(self.vgs) == 1:
                self.vgs *= self.device_count
                self.device_count = 1
            else:
                self.insufficient_param_count('vgs', self.device_count)
        for i, j in zip(self.bricks, self.vgs):
            vgnames = {}
            vgnames['brick'] = i
            vgnames['vg'] = j
            data.append(vgnames)
        self.section_dict['vgnames'] = filter(None, data)
        self.vgs = self.section_dict['vgs']
        Global.logger.info("Creating volume group %s running %s"\
                           %(self.vgs, VGCREATE_YML))
        if self.vgs:
            self.run_playbook(VGCREATE_YML)

    def write_thinp_names(self):
        self.pools = self.