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

# Copyright 2012-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.

from __future__ import absolute_import
import socket
from calculate.consolegui import qt

from .more import LabelWordWrap, show_msg, get_icon

def passphrase_callback(v):
    if type(v) == int or not v:
        return ""
    return bytes(v, "UTF-8")

def generateRSAKey():
    from M2Crypto import RSA, m2
    return RSA.gen_key(2048, m2.RSA_F4)

def makePKey(key):
    from M2Crypto import EVP
    pkey = EVP.PKey()
    pkey.assign_rsa(key)
    return pkey

class RequestCreate (qt.QWidget):
    def __init__(self, parent, ClientObj, key, cert_path, server_host_name):
        super().__init__()
        self.ClientObj = ClientObj
        self._parent = parent

        self.key = key
        self.cert_path = cert_path
        self.server_host_name = server_host_name

        self.mainlayout = qt.QGridLayout()
        self.mainlayout.setColumnStretch(0,0)
        self.mainlayout.setColumnStretch(1,1)
        # Add HostName field        
        host_name = socket.getfqdn()
        list_host_name = host_name.split('.')
        result_host_name = list_host_name[0]+"@"+server_host_name

        self.mainlayout.addWidget(LabelWordWrap(_('User@Server_HostName'), \
                                              self),0,0, qt.Qt.AlignRight)
        self.host_name = qt.QLineEdit(result_host_name, self)
        self.mainlayout.addWidget(self.host_name, 0,1)
        
        # Add UserName field
        username = ClientObj.VarsApi.Get('ur_fullname')
        suffixPort = ":%s"%ClientObj.VarsApi.Get('core.cl_core_port')

        # username = username.decode('utf-8')
        username = username
        self.mainlayout.addWidget(LabelWordWrap(_('User Name'), self),1,0,
                                                qt.Qt.AlignRight)
        self.user_name = qt.QLineEdit(username, self)
        self.mainlayout.addWidget(self.user_name, 1,1)

        # Add Organization name field
        self.mainlayout.addWidget(qt.QLabel(_('Organization Name'), self),\
                                                2, 0, qt.Qt.AlignRight)
        self.org_name = qt.QLineEdit('Company', self)
        self.mainlayout.addWidget(self.org_name, 2,1)

        # Add Network address field
        self.mainlayout.addWidget(LabelWordWrap(_('Network address'), self), \
                                                3,0,qt.Qt.AlignRight)
        self.netw_adr = qt.QLineEdit(host_name+suffixPort, self)
        self.mainlayout.addWidget(self.netw_adr, 3,1)

        # Add State name field
        self.mainlayout.addWidget(LabelWordWrap(_("City"), self),4,0, \
                                                qt.Qt.AlignRight)
        self.state_name = qt.QLineEdit('My_State', self)
        self.mainlayout.addWidget(self.state_name, 4,1)

        # Add Country field
        self.mainlayout.addWidget(LabelWordWrap \
                                (_('Country (a two-character tag)'), self),
                                5,0,qt.Qt.AlignRight)
        self.country = qt.QLineEdit('Ru', self)
        # only 2 words
        rx = qt.QRegExp ("^[a-zA-Z]{0,2}$")
        country_validator = qt.QRegExpValidator(rx, self)
        self.country.setValidator(country_validator)

        self.mainlayout.addWidget(self.country, 5,1)

        button_layout = qt.QHBoxLayout()
        button_layout.setAlignment(qt.Qt.AlignRight)

        # Add Password field
        self.mainlayout.addWidget(LabelWordWrap(_('Password'),\
                                  self), 6,0,qt.Qt.AlignRight)
        self.passwd_lineedit = qt.QLineEdit('', self)
        self.passwd_lineedit.setEchoMode(self.passwd_lineedit.Password)
        self.mainlayout.addWidget(self.passwd_lineedit, 6,1)

        # Add create button
        self.CreateButton = qt.QPushButton(_('Create a signature request'),
                                              self)
        self.CreateButton.setFixedWidth(self.CreateButton.sizeHint().width())
        self.CreateButton.clicked.connect(self.create_req)
        button_layout.addWidget(self.CreateButton)

        # Add cancel button
        self.CancelButton = qt.QPushButton(_('Cancel'), self)
        self.CancelButton.setFixedWidth(self.CancelButton.sizeHint().width())
        self.CancelButton.clicked.connect(self.close)
        button_layout.addWidget(self.CancelButton)
        
        self.mainlayout.addLayout(button_layout,7,0,1,2,qt.Qt.AlignRight)

        self.setLayout(self.mainlayout)

        # for clear memory after closed this window
        self.setAttribute(qt.Qt.WA_DeleteOnClose)
        
        self.setWindowTitle (_('Create a signature request'))
        self.setWindowIcon(get_icon("view-certificate"))

        self.setFocus()
        self.move(50+parent.frameGeometry().x(), \
                          50+parent.frameGeometry().y())
        self.setMinimumWidth(600)
        self.setFixedHeight(self.sizeHint().height())
        self.show()
        
    def create_req(self):
        if len(self.country.text()) != 2:
            show_msg(_('The \"Country\" field must be two-character'), \
                     _('Input error'))
            return
        from M2Crypto import X509
#########################################
        private_key_passwd = self.passwd_lineedit.text()
        rsa = generateRSAKey()
        rsa.save_key(self.key + '_pub', cipher = None,
                     callback = lambda *unused: b"")

        pkey = makePKey(rsa)
        if not passphrase_callback(private_key_passwd):
            pkey.save_key(self.key, cipher = None,
                          callback = lambda *unused: b"")
        else:
            pkey.save_key(self.key,\
                            callback= lambda *unused: bytes(private_key_passwd, "UTF-8"))
#########################################
        req = X509.Request()
        req.set_version(req.get_version())
        req.set_pubkey(pkey)
        name = X509.X509_Name()
#######
        # Create NAME value
        name.CN = self.host_name.text() or ""
        User_name = self.user_name.text()
        name.OU = User_name.encode('utf-8') or ""
        Organization = self.org_name.text()
        name.O = Organization.encode('utf-8') or ""
        name.L = self.netw_adr.text() or ""
        State = self.state_name.text()
        name.ST = State.encode('utf-8') or ""
        name.C = self.country.text() or ""
#######
        req.set_subject_name(name)

        ext1 = X509.new_extension('nsComment', 'Auto Generated')
        extstack = X509.X509_Extension_Stack()
        extstack.push(ext1)
        req.add_extensions(extstack)
        req.sign(pkey, 'md5')
#########################################
        
        crtreq = str(req.as_pem(), 'utf-8')
        crtfile = open(self.cert_path + '/%s.csr' %self.server_host_name, 'w')
        crtfile.write(crtreq)
        crtfile.close()
        self.close()
        self._parent.end_send()
#########################################
