# -*- coding: utf-8 -*-
import datetime
import re
import time
import logging

from odoo import models, fields, api, exceptions, SUPERUSER_ID
from core.middleware.utils import today
from odoo.tools.safe_eval import safe_eval

_logger = logging.getLogger(__name__)


class BaseExecutor(models.TransientModel):
    _name = 'jd.base.executor'
    _order = 'id desc'
    _description = u'页面方法执行'

    execute_code = fields.Text(u'代码段', requred=True)
    result = fields.Text(u'执行结果', readonly=True)

    @api.model
    def show_date(self, date_str):
        raise exceptions.ValidationError(date_str)

    @api.multi
    def on_execute(self):
        self.ensure_one()
        item = self[0]
        if not item.execute_code:
            raise exceptions.ValidationError(u'输入代码段错误。')

        # 非系统管理员禁止执行危险语句：
        # 数据库操作：1.DROP DATABASE;2.ALTER DATABASE;3.RENAME DATABASE;
        # 表操作：1.DROP TABLE;2.TRUNCATE TABLE;3.ALTER TABLE;4.RENAME TABLE;5.DROP COLUMN;6.RENAME COLUMN;
        # 记录操作：1.DELETE FROM;2.不带WHERE的UPDATE
        if 'cr.execute' in item.execute_code:
            # 转大写后判断，且需要处理存在多个空格或换行等字符的语句
            code_upper = re.sub(r'\s+', ' ', item.execute_code.upper())
            if 'UPDATE' in code_upper and 'WHERE' not in code_upper:
                raise exceptions.ValidationError(u'不允许执行不带WHERE的UPDATE语句！')
            if 'DELETE FROM' in code_upper and 'WHERE' not in code_upper:
                raise exceptions.ValidationError(u'不允许执行不带WHERE的DELETE语句！')
            if self.env.user.id != SUPERUSER_ID:
                if 'DELETE FROM' in code_upper:
                    raise exceptions.ValidationError(u'非系统账号不允许执行删除语句！')
                elif any(
                    x in code_upper for x in (
                        'DROP DATABASE', 'ALTER DATABASE', 'RENAME DATABASE',
                        'DROP TABLE', 'TRUNCATE TABLE', 'ALTER TABLE', 'RENAME TABLE', 'DROP COLUMN', 'RENAME COLUMN',
                    )
                ):
                    raise exceptions.ValidationError(u'非系统账号禁止修改数据库或表结构')

        eval_context = {
            'time': time,
            'datetime': datetime,
            'today': today,
            'self': self,
            'exceptions': exceptions
        }
        start_time = time.time()
        result = safe_eval(item.execute_code, eval_context)
        end_time = time.time()
        self.env['ir.logging'].jdg_sudo().create({
            'dbname': self.env.cr.dbname,
            'type': 'server',
            'name': '%s-[%s]%s' % (self._name, self.env.user.login, self.env.user.partner_id.name),
            'level': 'info',
            'path': self._name,
            'line': item.id,
            'func': 'on_execute',
            'message': {
                'execute_code': item.execute_code,
                'result': str(result),
                'spend': '%s s' % (end_time - start_time)
            },
        })
        item.result = str(result)
        _logger.info("executor result:" + str(result))
