from .services.base_service import Base_service
import sys
import os
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 shutil
import subprocess
import string
import uuid
import time 
from .docker_installer import Docker_installer
from .services import *


class Last_Check(Base_service):
    def preload(self):
#        with Docker_installer(logger_level = self.logger_level) as run:
#            pass
        # self.menu = (
        #     ('cs-rabbitmq','Р7-КС24: MQTT-служба очередей','ON'),
        #     ('cs-postgres','Р7-КС24: Служба базы данных','ON'),
        #     ('cs-filestorage','Р7-КС24: Служба файлового хранилища','ON'),
        #     ('cs-searchapi','Р7-КС24: Служба поиска','ON'),
        #     ('cs-registry','Р7-КС24: Реестр служб','ON'),
        #     ('cs-ssoapi','Р7-КС24: Служба авторизации SSO','ON'),
        #     ('cs-api','Р7-КС24: Служба API','ON'),
        #     ('cs-processing','Р7-КС24: Служба процессинга','ON'),
        #     ('cs-draw','Р7-КС24: Компонент Р7-Графика','ON'),
        #     ('cs-frontend','Р7-КС24: Веб-интерфейс','ON'),
        # );
        pass
    def postload(self, **kwarg):

        self.get_requests(**kwarg);
        if self.BACK_MENU[0]==True:
            return        
        self.deploy();
        return self;

    def load_images(self, images: list = []):
        outputs=[];
        # for image in images:
        #     with open(f'{sys.path[0]}/images/{image}', 'rb') as file:
        #         print(f'\nЗагружаю dump образов:\n{sys.path[0]}/images/{image}\n');
        #         try:
        #             outputs = outputs + self.dockercli.images.load(file);
        #         except:
        #             self.msgbox(f'Произошла ошибка при загрузке docker-образов из dump-файла {image}');
#        self.msgbox(f'''Загружены docker-образы:\n''' + [''.join(output.attrs["RepoTags"][0]+"""\n""") for output in outputs]);

    def build_compose(self):
        self.logger.info(f'Открываю compose-файл template.yaml на запись')
        # try:        
        #     with open(f'{self.INSTALL_NEW_PATH[-1]}/template.yaml', 'r') as file:
        #         compose_data = yaml.safe_load(file)
        # except FileNotFoundError:
        #     self.msgbox(f'в каталоге {self.INSTALL_NEW_PATH[-1]} отсутствует файл template.yaml')
        #     return
        # except PermissionError:
        #     self.msgbox(f'в каталоге {self.INSTALL_NEW_PATH[-1]} отсутствует доступ к файлу template.yaml')
        #     return            
        # if 'cs-rabbitmq' in compose_data['services']:
        #     compose_data['services']['cs-rabbitmq']['image'] = f'{self.CS_RABBIT_IMAGE_NAME[-1]}:{self.CS_RABBIT_IMAGE_VERSION[-1]}'
        # else:
        #     print(f"Сервис cs-rabbitmq не найден в template.yaml")
        # # Сохраняем изменения обратно в файл

        # with open(f'{self.INSTALL_NEW_PATH[-1]}/template.yaml', 'w') as file:
        #     yaml.dump(compose_data, file, default_flow_style=False)

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

    def build_configs(self):
        self.logger.info(f'Произвожу поиск файлов-шаблонов конфигураций')

    def deploy(self):

        command = ['/usr/bin/openssl', 'genrsa',  '-out', f'{self.INSTALL_NEW_PATH[-1]}/ca-key.pem', '2048']
        return_code, stdout, stderr = self.subprocess(command, fd_stderr=sys.stdout)
        if return_code != 0:
            self.logger.error(f'При попытке запуска команды ({command}) произошли ошибки')
            for err in stderr: self.logger.error(err) if 'error' in err.lower() else self.logger.info(err)
            self.msgbox(f'При генерации ключа корневого сертификата произошли ошибки. Обратитесь в службу технической поддержки Р7-офис.')
        else:
            for err in stderr: self.logger.debug(err)
            self.logger.info('Генерация ключа корневого сертификата без ошибок.')

        subj='/CN=DevOps CA/O=R7/C=RU'
        command = ['/usr/bin/openssl', 'req', '-x509', '-new', '-key', f'{self.INSTALL_NEW_PATH[-1]}/ca-key.pem', '-days', '10000', '-out', f'{self.INSTALL_NEW_PATH[-1]}/ca.pem', '-subj', subj]
        return_code, stdout, stderr = self.subprocess(command, fd_stderr=sys.stdout)
        if return_code != 0:
            self.logger.error(f'При попытке запуска команды ({command}) произошли ошибки')
            for err in stderr: self.logger.error(err) if 'error' in err.lower() else self.logger.info(err)
            self.msgbox(f'При генерации корневого сертификата произошли ошибки. Обратитесь в службу технической поддержки Р7-офис.')
        else:
            for err in stderr: self.logger.debug(err)
            self.logger.info('Генерация корневого сертификата без ошибок.')

        command = ['/usr/bin/openssl', 'genrsa',  '-out', f'{self.INSTALL_NEW_PATH[-1]}/privkey.key', '2048']
        return_code, stdout, stderr = self.subprocess(command, fd_stderr=sys.stdout)
        if return_code != 0:
            self.logger.error(f'При попытке запуска команды ({command}) произошли ошибки')
            for err in stderr: self.logger.error(err) if 'error' in err.lower() else self.logger.info(err)
            self.msgbox(f'При генерации ключа конечного сертификата произошли ошибки. Обратитесь в службу технической поддержки Р7-офис.')
        else:
            for err in stderr: self.logger.debug(err)
            self.logger.info('Генерация ключа конечного сертификата без ошибок.')
        content = f"""[req]
distinguished_name = req_distinguished_name
req_extensions = req_ext
prompt = no
[req_distinguished_name]
C = RU
ST = Moscow
L = Moscow
O = R7
OU = DevOps
CN = www.{self.CS_FRONTEND_DOMAIN[-1]}

[req_ext]
keyUsage = keyEncipherment, dataEncipherment, digitalSignature
extendedKeyUsage = serverAuth
subjectAltName = @alt_names

[alt_names]
DNS.1 = *.{self.CS_FRONTEND_DOMAIN[-1]}
"""

        path=f'{self.INSTALL_NEW_PATH[-1]}/tls.cnf'
        try:
            dir = os.path.dirname(path)
            if dir:
                os.makedirs(dir, exist_ok=True)
            with open(path, 'w', encoding='utf-8') as f:
                f.write(content)
        except OSError as e:
            print(f"Ошибка при создании или записи файла '{path}': {e}")
        except Exception as e:
            print(f"Неожиданная ошибка: {e}")
        else:
            print(f"Файл '{path}' успешно создан.")

        command = [f'/usr/bin/openssl', 'req', '-new', '-sha256', '-out', f'{self.INSTALL_NEW_PATH[-1]}/cert.csr', '-key', f'{self.INSTALL_NEW_PATH[-1]}/privkey.key', '-config', f'{self.INSTALL_NEW_PATH[-1]}/tls.cnf']
        return_code, stdout, stderr = self.subprocess(command, fd_stderr=sys.stdout)
        if return_code != 0:
            self.logger.error(f'При попытке запуска команды ({command}) произошли ошибки')
            for err in stderr: self.logger.error(err) if 'error' in err.lower() else self.logger.info(err)
            self.msgbox(f'При генерации корневого сертификата произошли ошибки. Обратитесь в службу технической поддержки Р7-офис.')
        else:
            for err in stderr: self.logger.debug(err)
            self.logger.info('Генерация корневого сертификата без ошибок.')

        command = [f'/usr/bin/openssl', 'x509', '-req', '-in', f'{self.INSTALL_NEW_PATH[-1]}/cert.csr', '-CA', f'{self.INSTALL_NEW_PATH[-1]}/ca.pem', '-CAkey', f'{self.INSTALL_NEW_PATH[-1]}/ca-key.pem', '-CAcreateserial', '-out', f'{self.INSTALL_NEW_PATH[-1]}/fullchain.crt', '-days', '1000', '-extensions', 'req_ext', '-extfile', f'{self.INSTALL_NEW_PATH[-1]}/tls.cnf']
        return_code, stdout, stderr = self.subprocess(command, fd_stderr=sys.stdout)
        if return_code != 0:
            self.logger.error(f'При попытке запуска команды ({command}) произошли ошибки')
            for err in stderr: self.logger.error(err) if 'error' in err.lower() else self.logger.info(err)
            self.msgbox(f'При генерации корневого сертификата произошли ошибки. Обратитесь в службу технической поддержки Р7-офис.')
        else:
            for err in stderr: self.logger.debug(err)
            self.logger.info('Генерация корневого сертификата без ошибок.')
            self.msgbox(f'Сертификат и Ключ сгенерированы, добавьте в доверенные на клиентах файл ca.pem')

    def get_requests(self, prefix_env: str = "CS", dialog: list = None, external:bool = False, **kwarg):
        dialogs = dialog if isinstance(dialog, list) else [
            {
                "env": f'INSTALL_NEW_PATH',
                "enable": None,
                'msg': (
                    f'Р7-Корпоративный сервер:\n\nУкажите путь, где расположить сертификат',
                    f'Путь до директории до каталога хранения обязателен',
                    f'Указанный путь не найден'
                ),
                "func_parse": self.parse_path_dir(),
                "func_check": self.check_extended_dir(),
                "func_visibility": self.visibility_detalization(),
                "detalization": 1
            },
            {
                "env": f'CS_FRONTEND_DOMAIN',
                "enable": True,
                "msg": (
                    f'Введите имя домена',
                    f'Имя домена обязательно к заполнению.',
                    None
                ),
                "func_check": self.check_domain(),
                "func_parse": self.parse_default()
            },            
        ];
        self.get_dialogs(dialogs)
    
