# -*- coding: utf-8 -*-

# Copyright 2010-2016 Mir Calculate. http://www.calculate-linux.org
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.

import sys
from calculate.core.server.func import Action, Tasks
from calculate.install.distr import DistributiveError
from calculate.install.migrate_users import MigrationError
from calculate.install.variables.autopartition import AutopartitionError
from calculate.lib.utils.partition import VolumesError
from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate, _
from calculate.lib.cl_template import TemplatesError
from calculate.lib.utils.files import FilesError
from calculate.install.install import InstallError

setLocalTranslate('cl_install3', sys.modules[__name__])
__ = getLazyLocalTranslate(_)


class ClInstallAction(Action):
    """
    Установка системы
    """
    # ошибки, которые отображаются без подробностей
    native_error = (FilesError, MigrationError, TemplatesError, VolumesError,
                    InstallError, AutopartitionError, DistributiveError)
    successMessage = None
    failedMessage = None
    interruptMessage = None

    # список задач для действия
    tasks = [
        # авторазметка диска
        {'name': 'autopartition',
         'message': __("Creating a new partition table"),
         'method': "Install.autopartition(cl_autopartition_scheme_builder,"
                                         "cl_autopartition_device,"
                                         "cl_autopartition_disk_dev)",
         'condition': lambda dv: dv.Get('cl_autopartition_set') == 'on'},
        # форматирование разделов на которые устанавливается дистрибутив
        {'name': 'format',
         'message': __("Formatting the partitions"),
         'method': 'Install.format(cl_target)',
         'condition': lambda dv: dv.Get('cl_target').needFormat},
        # распаковка дистрибутива
        {'name': 'unpack',
         'message': __("Unpacking the system image to the target"),
         'method': 'Install.unpack(cl_image,cl_target,os_install_linux_files)',
         },
        # отметка что установка идет на HDD
        {'name': 'hdd',
         'condition': lambda dv: dv.Get(
             'os_install_root_type') != 'flash' and
                                 dv.Get('os_install_pxe') == 'off'},
        # копирование clt шаблонов
        {'name': 'hdd:copy_clt',
         'message': __("Copying clt templates to the new system"),
         'method': 'Install.copyClt(cl_source,cl_target,cl_template_clt_path)'
         },
        # копирование прочих файлов
        {'name': 'hdd:copy_other',
         'message': __("Copying other settings to the new system"),
         'method': 'Install.copyOther(cl_source,cl_target)',
         'condition': lambda dv: dv.Get('os_root_type') != "livecd",
         },
        # перемонтирование ntfs для определения windows
        {'name': 'hdd:remount_ntfs',
         'method': 'Install.remountNTFS()',
         'essential': False,
         },
        # наложение шаблонов при установке на жесткий диск
        {'name': 'hdd:apply_templates',
         'message': __("Updating the configuration"),
         # наложить шаблоны в установленный дистрибутив, включая clt шаблоны
         # без использования фильтров по clt шаблонам
         'method': 'Install.applyTemplates(cl_target,True,False,None)',
         },
        # наложение шаблонов при PXE установке
        {'name': 'apply_templates_pxe',
         'message': __("Configuring PXE install"),
         # наложить шаблоны в установленный дистрибутив, исключая clt
         # без использования фильтров по clt шаблонам
         'method': 'Install.applyTemplates(None,False,False,None)',
         'condition': lambda dv: dv.Get('os_install_pxe') == 'on'
         },
        # наложение шаблонов при установке на flash диск
        {'name': 'apply_templates_flash',
         'message': __("Configuring Flash install"),
         # наложить шаблоны в установленный дистрибутив, исключая clt
         # без использования фильтров по clt шаблонам
         'method': 'Install.applyTemplates(None,False,False,cl_target)',
         'condition': lambda dv: dv.Get('os_install_root_type') == "flash"
         },
        # подключить точки монтирования bind
        {'name': 'hdd:mount_bind',
         'message': __("Post-install configuration"),
         'method': "Install.mountBind(cl_target)",
         },
        # перенос пользователей
        {'name': 'hdd:user_migrate',
         'message': __("Migrating users"),
         'method': 'Install.userMigrate(cl_target,cl_migrate_data,'
                   'cl_migrate_root_pwd)',
         },
        # прописывание локальных администраторов
        {'name': 'hdd:write_admins',
         'method': 'Install.update_admin_ini()',
         },
        # подготовка загрузчика
        {'name': 'prepare_boot',
         'message': __("Preparing the system for reboot"),
         'method': 'Install.prepareBoot(cl_target)',
         'condition': lambda dv: (dv.Get('os_install_mbr') or
                                  dv.Get('os_install_uefi_set') == 'on') and
                                 dv.Get('os_install_pxe') == 'off'},
        # отключение исходного дистрибутива
        {'name': 'umount_source',
         'message': __("Letting go the source distribution"),
         'method': 'Install.umount(cl_image)',
         'condition': lambda dv: dv.Get('cl_image') and dv.Get(
             'cl_image').childs,
         'depend': Tasks.has("unpack")},
        # отключение установленного дистрибутива
        {'name': 'umount_target',
         'message': __("Unmounting the target system volume"),
         'method': 'Install.umount(cl_target)',
         'condition': lambda dv: dv.Get('cl_target') and dv.Get(
             'cl_target').childs,
         'depend': Tasks.has("unpack")},
        # вывести сообщение в случае успеха
        {'name': 'success',
         'message': __("System successfully installed!")},
        # вывести сообщение в случае ошибки
        {'name': 'failed',
         'message': __("Failed to install the system!"),
         'depend': (Tasks.failed() & Tasks.hasnot("interrupt"))},
        # вывести сообщение о том, что установка прервана пользователем
        {'name': 'intmessage',
         'message': __("Installation manually interrupted"),
         'depend': Tasks.has("interrupt")},
        # подтверждение на перезагрузку
        {'name': 'ask_reboot',
         'message': __("Would you like to reboot your computer "
                       "now to complete the installation?"),
         'confirm': 'no',
         'condition': lambda Get: (Get('os_install_pxe') == 'off' and
                                   Get('os_install_root_type') != "flash")
         },
        # перезагрузить компьютер
        {'name': 'reboot',
         'message': __("System reboot"),
         'command': '/sbin/reboot',
         'depend': Tasks.result("ask_reboot", eq='yes')
         }
    ]
