from .services.base_service import Base_service
import sys
import os
import re
from py_module.whiptail import Whiptail
import py_module.yaml as yaml
import py_module.docker as docker
import py_module.jinja2 as jinja
import subprocess
import string
import uuid
from .docker_installer import Docker_installer
from .services import *
from .services import base_service

class Team_install(Base_service):
    def preload(self):
        with Docker_installer(logger_level = self.logger_level) as run:
            pass
        self.logger.info('Инициализирую основные переменные')

        if not self.DETALIZATION:
            self.DETALIZATION = 1
        self.INSTALL_DUMP_PATH='./images'
        self.INSTALL_CONF_PATH='./configs_team'
        self.BACK_MENU=[False]

### ENVIRONMENT GERENAL
        self.DETALIZATION = 1

        self.dockercli = docker.from_env();

        self.menu = (
            ('mgmt-postgres','mgmt: служба postgres','ON'),
            ('mgmt-redis','mgmt: служба redis','ON'),
            ('mgmt-mongo','mgmt: служба mongo','ON'),
            ('mgmt-config-server','mgmt: служба config-server','ON'),
            ('mgmt-gateway','mgmt: служба gateway','ON'),
            ('mgmt-addressbook','mgmt: служба addressbook','ON'),
            ('mgmt-sso','mgmt: служба sso','ON'),
            ('mgmt-attach','mgmt: служба attach','ON'),
            ('mgmt-uploadserver','mgmt: служба uploadserver','ON'),
            ('mgmt-storage','mgmt: служба storage','ON'),
            ('mgmt-report','mgmt: служба report','ON'),
            ('mgmt-remote-control','mgmt: служба remote-control','ON'),
            ('mgmt-callchat','mgmt: служба callchat','ON'),
            ('mgmt-link-preview','mgmt: служба link-preview','ON'),
            ('mgmt-disk-api','mgmt: служба disk-api','ON'),
        );

        self.PREFIX_MAIL=['mail']
        self.PREFIX_TEAM=['team']
        self.TEAM_FQDN=['team.domain.ru']
        self.MEDIA_FQDN=['media.domain.ru']

        self.TEAM_CERT_CRT_PATH=['./configs/ssl']
        self.TEAM_CERT_CRT_FILE=['fullchain.crt']
        self.TEAM_CERT_KEY_PATH=['./configs/ssl']
        self.TEAM_CERT_KEY_FILE=['privkey.key']
        self.TEAM_HTTPS_PUBLISH_PORT=['443']
        self.TEAM_HTTP_PUBLISH_PORT=['80']
        self.MEDIA_HTTPS_PUBLISH_PORT=['443']
        self.MEDIA_HTTP_PUBLISH_PORT=['80']
        self.TEAM_UUID=['']
        self.TEAM_TOKEN=['']
        self.TEAM_HASH=['hash']        
        self.CS_TEAM_CLIENT_ID=['']
        self.CS_TEAM_CLIENT_SECRET=['']
        self.CS_PAGES_CLIENT_ID=['']
        self.CS_PAGES_CLIENT_SECRET=['']
        self.CS_FORMS_CLIENT_ID=['']
        self.CS_FORMS_CLIENT_SECRET=['']

### ENVIRONMENT TEAM-POSTGRES
        self.MGMT_PSQL_HOST=['team-psql']
        self.MGMT_PSQL_DB=['postgres']
        self.MGMT_PSQL_USER=['postgres']
        self.MGMT_PSQL_PWD=['pg_pass']
        self.MGMT_PSQL_PORT=['5432']
        self.MGMT_PSQL_IMAGE_NAME=['downloads.r7-office.ru:9011/r7office/team/astra/ubi18-postgres']
        self.MGMT_PSQL_IMAGE_VERSION=['15']
        self.MGMT_PSQL_CONTAINER_NAME=['team-postgres']
        self.MGMT_PSQL_HOST=['team-postgres']
        self.MGMT_PSQL_STORAGE=['']
### ENVIRONMENT TEAM-POSTGRES

### ENVIRONMENT TEAM-REDIS
        self.MGMT_REDIS_HOST=['team-redis']
        self.MGMT_REDIS_PORT=['6379']
        self.MGMT_REDIS_IMAGE_NAME=['downloads.r7-office.ru:9011/r7office/team/astra/ubi18-redis']
        self.MGMT_REDIS_IMAGE_VERSION=['7.4.1']
        self.MGMT_REDIS_CONTAINER_NAME=['team-redis']
### ENVIRONMENT TEAM-REDIS

### ENVIRONMENT TEAM-MONGO
        self.MGMT_MONGO_HOST=['team-mongo']
        self.MGMT_MONGO_PORT=['27017']
        self.MGMT_MONGO_IMAGE_NAME=['downloads.r7-office.ru:9011/r7office/team/astra/ubi18-mongo']
        self.MGMT_MONGO_IMAGE_VERSION=['6.0.18']
        self.MGMT_MONGO_CONTAINER_NAME=['team-mongo']
### ENVIRONMENT TEAM-MONGO

### ENVIRONMENT TEAM-CONFIG-SERVER
        self.MGMT_CONFIG_SERVER_HOST=['team-config-server']
        self.MGMT_CONFIG_SERVER_PORT=['8761']
        self.MGMT_CONFIG_SERVER_IMAGE_NAME=['downloads.r7-office.ru:9011/r7office/team/production/ubi18/config-server']
        self.MGMT_CONFIG_SERVER_IMAGE_VERSION=['1.11.0-489']
        self.MGMT_CONFIG_SERVER_CONTAINER_NAME=['team-config-server']
### ENVIRONMENT TEAM-CONFIG-SERVER

### ENVIRONMENT TEAM-ADDRESSBOOK
        self.MGMT_ADDRESSBOOK_HOST=['team-addressbook']
        self.MGMT_ADDRESSBOOK_PORT=['9100']
        self.MGMT_ADDRESSBOOK_IMAGE_NAME=['downloads.r7-office.ru:9011/r7office/team/production/ubi18/addressbook']
        self.MGMT_ADDRESSBOOK_IMAGE_VERSION=['1.11.0-489']
        self.MGMT_ADDRESSBOOK_CONTAINER_NAME=['team-addressbook']
### ENVIRONMENT TEAM-ADDRESSBOOK

### ENVIRONMENT TEAM-SSO
        self.MGMT_SSO_HOST=['team-sso']
        self.MGMT_SSO_PORT=['9200']
        self.MGMT_SSO_IMAGE_NAME=['downloads.r7-office.ru:9011/r7office/team/production/ubi18/sso']
        self.MGMT_SSO_IMAGE_VERSION=['1.11.0-489']
        self.MGMT_SSO_CONTAINER_NAME=['team-sso']
### ENVIRONMENT TEAM-SSO

### ENVIRONMENT TEAM-ATTACH
        self.MGMT_ATTACH_HOST=['team-attach']
        self.MGMT_ATTACH_PORT=['9400']
        self.MGMT_ATTACH_IMAGE_NAME=['downloads.r7-office.ru:9011/r7office/team/production/ubi18/attach']
        self.MGMT_ATTACH_IMAGE_VERSION=['1.11.0-489']
        self.MGMT_ATTACH_CONTAINER_NAME=['team-attach']
### ENVIRONMENT TEAM-ATTACH

### ENVIRONMENT TEAM-UPLOADSERVER
        self.MGMT_UPLOADSERVER_HOST=['team-uploadserver']
        self.MGMT_UPLOADSERVER_PORT=['9401']
        self.MGMT_UPLOADSERVER_IMAGE_NAME=['downloads.r7-office.ru:9011/r7office/team/production/ubi18/uploadserver']
        self.MGMT_UPLOADSERVER_IMAGE_VERSION=['1.11.0-489']
        self.MGMT_UPLOADSERVER_CONTAINER_NAME=['team-uploadserver']
### ENVIRONMENT TEAM-UPLOADSERVER

### ENVIRONMENT TEAM-STORAGE
        self.MGMT_STORAGE_HOST=['team-storage']
        self.MGMT_STORAGE_PORT=['80']
        self.MGMT_STORAGE_IMAGE_NAME=['downloads.r7-office.ru:9011/r7office/team/production/ubi18/storage']
        self.MGMT_STORAGE_IMAGE_VERSION=['1.11.0-489']
        self.MGMT_STORAGE_CONTAINER_NAME=['team-storage']
### ENVIRONMENT TEAM-STORAGE

### ENVIRONMENT TEAM-REPORT
        self.MGMT_REPORT_HOST=['team-report']
        self.MGMT_REPORT_PORT=['3555']
        self.MGMT_REPORT_IMAGE_NAME=['downloads.r7-office.ru:9011/r7office/team/production/ubi18/report']
        self.MGMT_REPORT_IMAGE_VERSION=['1.11.0-489']
        self.MGMT_REPORT_CONTAINER_NAME=['team-report']
### ENVIRONMENT TEAM-REPORT

### ENVIRONMENT TEAM-REMOTE-CONTROL
        self.MGMT_REMOTE_CONTROL_HOST=['team-remote-control']
        self.MGMT_REMOTE_CONTROL_PORT=['3556']
        self.MGMT_REMOTE_CONTROL_IMAGE_NAME=['downloads.r7-office.ru:9011/r7office/team/production/ubi18/remote-control']
        self.MGMT_REMOTE_CONTROL_IMAGE_VERSION=['1.11.0-489']
        self.MGMT_REMOTE_CONTROL_CONTAINER_NAME=['team-remote-control']
### ENVIRONMENT TEAM-REMOTE-CONTROL

### ENVIRONMENT TEAM-CALLCHAT
        self.MGMT_CALLCHAT_HOST=['team-callchat']
        self.MGMT_CALLCHAT_PORT=['9401']
        self.MGMT_CALLCHAT_IMAGE_NAME=['downloads.r7-office.ru:9011/r7office/team/production/ubi18/callchat']
        self.MGMT_CALLCHAT_IMAGE_VERSION=['1.11.0-489']
        self.MGMT_CALLCHAT_CONTAINER_NAME=['team-callchat']
### ENVIRONMENT TEAM-CALLCHAT

### ENVIRONMENT TEAM-LINK-PREVIEW
        self.MGMT_LINK_PREVIEW_HOST=['team-link-preview']
        self.MGMT_LINK_PREVIEW_PORT=['8002']
        self.MGMT_LINK_PREVIEW_IMAGE_NAME=['downloads.r7-office.ru:9011/r7office/team/production/ubi18/link-preview']
        self.MGMT_LINK_PREVIEW_IMAGE_VERSION=['1.11.0-489']
        self.MGMT_LINK_PREVIEW_CONTAINER_NAME=['team-link-preview']
### ENVIRONMENT TEAM-LINK-PREVIEW

### ENVIRONMENT TEAM-GATEWAY
        self.MGMT_GATEWAY_HOST=['team-gateway']
        self.MGMT_GATEWAY_PORT=['443']
        self.MGMT_GATEWAY_IMAGE_NAME=['downloads.r7-office.ru:9011/r7office/team/production/ubi18/gateway']
        self.MGMT_GATEWAY_IMAGE_VERSION=['1.11.0-489']
        self.MGMT_GATEWAY_CONTAINER_NAME=['team-gateway']
### ENVIRONMENT TEAM-GATEWAY

### ENVIRONMENT TEAM-DISK-API
        self.MGMT_DISK_API_HOST=['team-disk-api']
        self.MGMT_DISK_API_PORT=['9101']
        self.MGMT_DISK_API_IMAGE_NAME=['downloads.r7-office.ru:9011/r7office/team/production/ubi18/disk-api']
        self.MGMT_DISK_API_IMAGE_VERSION=['1.11.0-489']
        self.MGMT_DISK_API_CONTAINER_NAME=['team-disk-api']
### ENVIRONMENT TEAM-DISK-API

        self.select_components=None
        self.dockercli = docker.from_env();

        self.services = {}
        for service in self.menu:
            getattr(self,"services")[service[0].replace('-','_')] = getattr(globals()[service[0].replace('-','_')], service[0].replace('-','_'))


        self.components={};

        self.compose={
            'services': {},
            'networks': {
                'external': {},
                'internal': {},
            },
            'volumes': {
                'postgres_data':{},
                'redis_data':{},
                'mongo-data': {},
                'storage-data': {},
                'storage-tmp-data': {},
            }
        };
        self.select_components=None
        self.dockercli = docker.from_env();

    def postload(self, **kwarg):
        self.get_service()
#        self.get_requests(**kwarg);
        if self.BACK_MENU[0]==True:
            return
        self.load_images(['callchat.tar.gz','addressbook.tar.gz','attach.tar.gz','uploadserver.tar.gz','link-preview.tar.gz','remote-control.tar.gz','storage.tar.gz','sso.tar.gz','report.tar.gz','gateway.tar.gz','config-server.tar.gz','sync-r7.tar.gz','disk-api.tar.gz','ubi18-redis.tar.gz','ubi18-postgres.tar.gz','ubi18-mongo.tar.gz']);
        base_ser = base_service.Base_service()
        test=base_ser.status_dns(f"{self.TEAM_FQDN[-1]}")
        test2=base_ser.status_ram(8)
        test3=base_ser.status_proc(4)
#        test4=base_ser.status_host_port(self)
        test5=base_ser.status_hdd()
        self.build_compose();
        if self.form.yesno(test+test2+test3, default="yes"):
            if self.form.yesno(test5, default="yes"):
                self.build_configs()
                self.deploy()
            else:
                return
        else:
            return
        return self;

    def load_images(self, images: list = []):
        outputs=[];
        self.logger.info(f'Начинаю импорт дампа образов: {images}')
        for image in images:
            self.logger.debug(f'Открываю файл дампа: {self.INSTALL_DUMP_PATH}/{image}')
            if os.path.isfile(f'{self.INSTALL_DUMP_PATH}/{image}'):
                with open(f'{self.INSTALL_DUMP_PATH}/{image}', 'rb') as file:
                    print(f'\nЗагружаю dump образов:\n{sys.path[0]}/images/{image}\n');
                    self.logger.info(f'Загружаю dump образов: {self.INSTALL_DUMP_PATH}/{image}')
                    try:
                        outputs = outputs + self.dockercli.images.load(file);
                    except:
                        self.logger.error(f'Произошла ошибка при загрузке docker-образов из dump-файла: {image}')
                        return self.msgbox(f'Произошла ошибка при загрузке docker-образов из dump-файла: {image}')
            else:
                self.logger.error(f'Файл dump образов отсутствует: {self.INSTALL_DUMP_PATH}/{image}')

    def get_service(self, exit_target = None):
        if self.DETALIZATION > 2:# and self.DETALIZATION < 6:
            self.logger.info('Вывожу запрос у пользователя списка устанавливаемых компонентов.')
            self.response = self.form.checklist(msg = 'Выберите устанавливаемые компоненты:', items = self.menu);
        else:
            self.response = ([
                'mgmt-postgres',
                'mgmt-redis',
                'mgmt-mongo',
                'mgmt-config-server',
                'mgmt-gateway',
                'mgmt-addressbook',
                'mgmt-sso',
                'mgmt-attach',
                'mgmt-uploadserver',
                'mgmt-storage',
                'mgmt-report',
                'mgmt-remote-control',
                'mgmt-callchat',
                'mgmt-link-preview',
                'mgmt-disk-api',
                ], 0);
        if not self.response[1]:
            self.select_components = self.response[0];
            self.logger.info(f'Выбраны компоненты: {self.select_components}')
#            print (self.select_components);
            for item in self.select_components:
                print(item)
                self.logger.info(f'Вызываю модуль: {item.replace("-","_")}.py')
                with self.services[item.replace('-','_')](**dict(filter(lambda item: item[0]==item[0].upper(), vars(self).items())), select_components = self.select_components, logger_level = self.logger_level) as run:
                    run.go();
                    if self.BACK_MENU[0]==True:
                        return        
                    for name, value in run.get_constants().items():
                        setattr(self, name, value);
#                    print(run.get_service())
                    self.components.update(run.get_service())
        return self;

    def build_compose(self):

        self.compose['services'] = self.components;
        self.logger.info(f'Открываю compose-файл team-compose.yaml на запись')

        with open('team-compose.yaml', 'w') as file:
            self.logger.info(f'Выгружаю compose-файл team-compose.yaml')
            yaml.dump(self.compose, file, sort_keys=False)
#            yaml.dump(file, default_flow_style=False, sort_keys=False)

        print(f"Переменная окружения обновлена ")
        self.logger.info(f'Выгружаю compose-файл team-compose.yaml')        

    def build_configs(self):
        self.logger.info(f'Произвожу поиск файлов-шаблонов конфигураций')
        for root, dirs, files in os.walk(self.INSTALL_CONF_PATH):
            for file in files:
                if file.endswith('.j2'):
                    self.logger.info(f'Вызываю шаблонизатор Jinja2 на файл {root}/{file}')
                    env = jinja.Environment(loader=jinja.FileSystemLoader([root]))
                    template = env.get_template(file);
                    self.logger.info(f'Открываю файл {root}/{file.replace(".j2", "")} на запись.')
                    with open(f'{root}/{file.replace(".j2", "")}', 'w') as f:
                        self.logger.info(f'Произвожу рендеринг шаблона и экспорт в файл')
                        f.write(template.render(self.__dict__));
                        self.logger.info(f'Файл {root}/{file.replace(".j2", "")} создан.')

    def deploy(self):
        print (f'\n\nИзменяю параметры контейнеров.\n\n############\n#### ВНИМАНИЕ: НЕ ОСТАНАВЛИВАЙТЕ ПРОЦЕСС\n############\n\n');

        #command = [f'{sys.path[0]}/runtime/docker-plugins/docker-compose', '-f', f'{sys.path[0]}/team-compose.yaml', 'up', '-d']#, '-V']#, '--remove-orphans']#'--force-recreate', '-d', '-V', '--remove-orphans']
        command = [f'{sys.path[0]}/runtime/docker/docker', 'compose', '--project-name', 'team','-f', f'{sys.path[0]}/team-compose.yaml', 'up', '-d', '-V']
        result = subprocess.run(command)
        if result.returncode != 0:
            self.logger.error(f'При попытке запуска команды ({command}) произошли ошибки')
            self.logger.error(result.stderr)
            self.msgbox(f'Установка не выполнена. Обратитесь в техподдержку Р7-Офис')
        else:
            self.logger.debug(result.stdout)
            self.logger.info('Docker Compose Plugin завершился без ошибок.')
            self.msgbox(f'Установка сервера управления Команды Р7 выполнена');
    
    # def get_requests(self, dialog: list = None, external:bool = False, **kwarg):
    #     dialogs = dialog if isinstance(dialog, list) else [
    #     ];
    #     self.get_dialogs(dialogs)
