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

# Copyright 2010-2013 Calculate Ltd. 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.lib.cl_lang import setLocalTranslate,getLazyLocalTranslate
from calculate.lib.utils.files import FilesError
from calculate.install.install import (MigrationError, TemplatesError,
                                  InstallError,
                                  AutopartitionError, DistributiveError)

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

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

    # список задач для дейсвия
    tasks = \
        [# авторазметка диска
         {'name':'autopartition',
          'message':__("Creating a new partition table"),
          'method':"Install.autopartition(cl_autopartition_table,"
                       "cl_autopartition_device,cl_autopartition_disk_data,"
                       "cl_autopartition_lvm_set,cl_autopartition_lvm_vgname,"
                       "cl_autopartition_bios_grub_set,"
                       "cl_autopartition_bios_grub_size)",
          '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':'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 dv:dv.Get('os_install_pxe') == 'off'},
         # перезагрузить компьютер
         {'name':'reboot',
          'message':__("System reboot"),
          'command':'/sbin/reboot',
          'depend':Tasks.result("ask_reboot",eq='yes')
         }
         ]
