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

# Copyright 2008-2012 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 os
import sys
import re

import cStringIO
import termios
# for symbol input
import tty
import time

from calculate.lib.utils.common import getpathenv
from calculate.lib.utils.files import runOsCommand

"""общие функции серверных программ"""

def unicList(listEl):
    """Уникальный список с сохранением порядка"""
    retList = []
    [not x in retList and retList.append(x) for x in listEl]
    return retList


def dialogYn(message):
    """Вывод сообщения, ожидание нажатия Y или n

    если Y - True если n - False"""

    def getChar():
        fd = sys.stdin.fileno()
        oldSet = termios.tcgetattr(fd)
        tty.setraw(fd)
        char = sys.stdin.read(1)
        termios.tcsetattr(fd, termios.TCSADRAIN, oldSet)
        return char

    def term(char):
        if ord(char) == 3:
            return None
        if char == "Y":
            return True
        elif char == "n":
            return False
        else:
            char = getChar()
            return term(char)

    sys.stdout.write(message + ":")
    char = getChar()
    res = term(char)
    sys.stdout.write("\n")
    return res


def dialogYesNo(message, reYes=re.compile("^ye?s?$",re.I),
                reNo=re.compile("^no?$",re.I)):
    """Вывод сообщения, ожидание набора Yes или No (в любом регистре)

    если Yes - True, если No - False"""
    sys.stdout.write(message + ": ")
    sys.stdout.flush()
    #strIn=sys.stdin.readline().lower().strip()
    strIn = raw_input("")    
    sys.stdout.write("\n")
    if reYes.match(strIn):
        return True
    elif reNo.match(strIn):
        return False
    else:
        return dialogYesNo(message, reYes, reNo)

def rawInput(promptText="", inputText=""):
    """Создает поле ввода

    promptText - текст перед полем ввода
    inputText - текст в поле ввода
    """
    # Вывод в строку ввода
    import readline
    if inputText:
        # Записываем текст для последующего вывода в строке ввода
        readline.set_pre_input_hook(lambda:\
                                readline.insert_text(inputText) or\
                                readline.redisplay())
    strInput = ""
    if promptText:
        # Получаем текст введенный пользователем
        strInput = raw_input(promptText)
    else:
        strInput = raw_input()
    if inputText:
        # Сбрасываем строку ввода
        readline.set_pre_input_hook(None)
    return strInput

def execProg(cmdStrProg, inStr=False, envProg={}):
        """Выполняет внешнюю программу

        Параметры:
        cmdStrProg     внешняя программа
        inStr          данные передаваемые программе на страндартный вход.
        Возвращаемые параметры:
        строки которые выведет внешняя программа или False в случае ошибки
        """
        env_path = {"PATH":getpathenv()}
        env = {}
        env.update(os.environ.items() + env_path.items() + envProg.items())
        retCode,programOut = runOsCommand(cmdStrProg,in_str=inStr,env_dict=env)
        if not retCode:
            return programOut
        return False

def genSleep(timeSleep=(0.2, 0.4, 0.8)):
    """Генератор задержек"""
    for t in timeSleep:
        time.sleep(t)
        yield(t)

def stringIsJpeg(string):
    """Определяет является ли строка - jpeg изображением"""
    if len(string)<8:
        return False
    FD = cStringIO.StringIO(string)
    isJpeg = False
    FD.seek(0, 0)
    (firstByte, secondByte) = FD.read(2)
    if (ord(firstByte) == 0xff and ord(secondByte) == 0xd8):
        (firstByte, secondByte) = FD.read(2)
        if (ord(firstByte) == 0xff and ord(secondByte) == 0xe0):
            isJpeg = True
    return isJpeg

def isCorrectStringNet(strNetworks, checkNet=True):
    """Проверяет на корректность строку доверительных сетей

    Выводит cписок сетей
    """
    splNet = strNetworks.replace(","," ").split(" ")
    if checkNet:
        checkIP = False
        res=re.compile("^\d\d?\d?\.\d\d?\d?\.\d\d?\d?\.\d\d?\d?\/\d\d?$")
    else:
        checkIP = True
        res=re.compile("^\d\d?\d?\.\d\d?\d?\.\d\d?\d?\.\d\d?\d?$")
    flagError = False
    networks = []
    for i in splNet:
        r = i.strip()
        if not r:
            continue
        find =res.search(r)
        if not find:
            flagError = True
            break
        else:
            splIP = map(lambda x: 255>=int(x.split("/")[0]) and\
                                x.split("/")[0], find.group().split("."))
            if not splIP[0] or splIP[0] and int(splIP[0]) == 0:
                flagError = True
                break
            if not splIP[3] or splIP[3] and int(splIP[3]) == 255:
                flagError = True
                break
            if checkNet:
                netList = r.split("/")
                if len(netList)==2:
                    try:
                        netMaskInt = int(netList[1])
                    except:
                        flagError = True
                        break
                    if netMaskInt>31 or netMaskInt<4:
                        flagError = True
                        break
                else:
                    flagError = True
                    break
            if checkIP and splIP[3] and int(splIP[3]) == 0:
                flagError = True
                break
            for t in splIP:
                if t == False:
                    flagError = True
                    break
        if flagError:
            break
        networks.append(r)
    if flagError:
        return False
    else:
        return list(set(networks))

def searchLineInFile(name, fileName, numEl=0):
    """Ищет строку в которой есть название разделенное ':'

    в файле похожем на /etc/passwd"""
    if os.path.exists(fileName):
        FD = open(fileName)
        lines = FD.readlines()
        FD.close()
        lineFound = ""
        for line in lines:
            if name == line.split(":")[numEl]:
                lineFound = line
                break
    if lineFound:
        return lineFound
    else:
        return False

def getMaxInFile(fileName, numMin, numMax, numEl=2):
    """Получаем максимальный номер из файла похожего на /etc/group"""
    lst = []
    lst.append(0)
    if os.path.exists(fileName):
        FD = open(fileName)
        lines = FD.readlines()
        FD.close()
        for line in lines:
            if not ':' in line:
                continue
            num = int(line.split(":")[numEl])
            if num<=numMax and num>=numMin:
                lst.append(num)
        return max(lst)
    return False

def chortToFullName(listNames, domain):
        """Из списка коротких имен получаем cписок полных имен

        К коротким именам добавляем домен, длинные выдаем как есть
        """
        listFillNames = []
        for name in listNames:
            if "." in name:
                listFillNames.append(name)
            else:
                listFillNames.append("%s.%s" %(name,domain))
        return listFillNames

def addInfoUser(name, uid, gid, comment):
        """Добавляем информацию о пользователе"""
        class user():
            """Информация о пользователе"""
            name = ""
            uid = ""
            gid = ""
            comment = ""
        us = user()
        us.name = name
        us.uid = uid
        us.gid = gid
        us.comment = comment
        return us

def addInfoGroup(name, gid, comment, rid="", type="", sid=""):
        """Добавляем информацию о группе"""
        class group():
            """Информация о группе"""
            name = ""
            gid = ""
            comment = ""
            rid = ""
            type = ""
            sid = ""
        gr = group()
        gr.name = name
        gr.gid = gid
        gr.comment = comment
        gr.rid = rid
        gr.type = type
        gr.sid = sid
        return gr
