#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
自动重启服务 - Web配置界面
使用Flask框架创建Web界面，用于配置自动重启服务的各项参数
"""

import os
import json
import time
import logging
from flask import Flask, render_template, request, redirect, url_for, flash, jsonify

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler('web_config.log'),
        logging.StreamHandler()
    ]
)
logger = logging.getLogger('web_config')

# 创建Flask应用
app = Flask(__name__)
app.config['SECRET_KEY'] = os.urandom(24)  # 用于flash消息

# 配置文件路径
CONFIG_FILE = 'reboot_config.json'
STATUS_FILE = 'reboot_status.json'

def load_config():
    """加载配置文件"""
    default_config = {
        "email": {
            "smtp_server": "smtp.example.com",
            "smtp_port": 587,
            "username": "",
            "password": "",
            "sender": "",
            "recipients": [""]
        },
        "reboot_warning_hours": 24,
        "reboot_warning_minutes": 30,
        "check_interval_seconds": 3600,
        "reboot_interval_days": 15  # 添加重启间隔天数配置
    }
    
    if not os.path.exists(CONFIG_FILE):
        logger.info(f'配置文件 {CONFIG_FILE} 不存在，创建默认配置')
        with open(CONFIG_FILE, 'w', encoding='utf-8') as f:
            json.dump(default_config, f, indent=4, ensure_ascii=False)
        return default_config
    
    try:
        with open(CONFIG_FILE, 'r', encoding='utf-8') as f:
            config = json.load(f)
        
        # 如果配置中缺少某些字段，使用默认值
        updated = False
        for key, value in default_config.items():
            if key not in config:
                config[key] = value
                updated = True
            elif isinstance(value, dict):
                for sub_key, sub_value in value.items():
                    if sub_key not in config[key]:
                        config[key][sub_key] = sub_value
                        updated = True
        
        # 如果配置有更新，保存更新后的配置
        if updated:
            with open(CONFIG_FILE, 'w', encoding='utf-8') as f:
                json.dump(config, f, indent=4, ensure_ascii=False)
        
        logger.info(f'配置文件 {CONFIG_FILE} 加载成功')
        return config
    except Exception as e:
        logger.error(f'加载配置文件失败: {e}')
        return default_config

def save_config(config):
    """保存配置文件"""
    try:
        with open(CONFIG_FILE, 'w', encoding='utf-8') as f:
            json.dump(config, f, indent=4, ensure_ascii=False)
        logger.info(f'配置已保存到 {CONFIG_FILE}')
        return True
    except Exception as e:
        logger.error(f'保存配置文件失败: {e}')
        return False

def get_service_status():
    """获取服务状态信息"""
    if not os.path.exists(STATUS_FILE):
        return {
            "status": "未初始化",
            "last_boot_time": "未知",
            "next_reboot_time": "未知",
            "time_left": "未知"
        }
    
    try:
        with open(STATUS_FILE, 'r', encoding='utf-8') as f:
            status = json.load(f)
        
        current_time = time.time()
        time_left = status['next_reboot_time'] - current_time
        
        # 格式化时间
        last_boot_str = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(status["last_boot_time"]))
        next_reboot_str = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(status["next_reboot_time"]))
        
        # 计算剩余时间
        if time_left > 0:
            days = int(time_left // (24 * 3600))
            hours = int((time_left % (24 * 3600)) // 3600)
            minutes = int((time_left % 3600) // 60)
            time_left_str = f"{days}天 {hours}小时 {minutes}分钟"
        else:
            time_left_str = "已到期"
        
        return {
            "status": "正常运行" if time_left > 0 else "等待重启",
            "last_boot_time": last_boot_str,
            "next_reboot_time": next_reboot_str,
            "time_left": time_left_str
        }
    except Exception as e:
        logger.error(f'读取状态文件失败: {e}')
        return {
            "status": "错误",
            "last_boot_time": "未知",
            "next_reboot_time": "未知",
            "time_left": "未知"
        }

@app.route('/')
def index():
    """首页 - 配置界面"""
    config = load_config()
    status = get_service_status()
    
    # 将收件人数组转换为逗号分隔的字符串
    recipients_str = ", ".join(config['email']['recipients'])
    
    return render_template('config.html', 
                           config=config, 
                           recipients_str=recipients_str,
                           status=status)

@app.route('/save', methods=['POST'])
def save():
    """保存配置"""
    try:
        # 获取表单数据
        smtp_server = request.form.get('smtp_server')
        smtp_port = int(request.form.get('smtp_port', 587))
        username = request.form.get('username')
        password = request.form.get('password')
        sender = request.form.get('sender')
        recipients_str = request.form.get('recipients', '')
        reboot_warning_hours = int(request.form.get('reboot_warning_hours', 24))
        reboot_warning_minutes = int(request.form.get('reboot_warning_minutes', 30))
        check_interval_seconds = int(request.form.get('check_interval_seconds', 3600))
        reboot_interval_days = int(request.form.get('reboot_interval_days', 15))  # 确保重启间隔天数被正确保存
        
        # 验证必填字段
        if not smtp_server or not username or not sender:
            flash('错误：SMTP服务器、用户名和发件人邮箱为必填项', 'error')
            return redirect(url_for('index'))
        
        # 处理收件人列表
        recipients = [r.strip() for r in recipients_str.split(',') if r.strip()]
        if not recipients:
            flash('错误：至少需要设置一个收件人邮箱', 'error')
            return redirect(url_for('index'))
        
        # 构建新配置
        new_config = {
            "email": {
                "smtp_server": smtp_server,
                "smtp_port": smtp_port,
                "username": username,
                "password": password,  # 保存密码
                "sender": sender,
                "recipients": recipients
            },
            "reboot_warning_hours": reboot_warning_hours,
            "reboot_warning_minutes": reboot_warning_minutes,
            "check_interval_seconds": check_interval_seconds,
            "reboot_interval_days": reboot_interval_days
        }
        
        # 保存配置
        if save_config(new_config):
            # 如果设置了新的重启间隔天数，更新状态文件中的下次重启时间
            if os.path.exists(STATUS_FILE):
                try:
                    with open(STATUS_FILE, 'r', encoding='utf-8') as f:
                        status = json.load(f)
                    
                    # 更新下次重启时间
                    status['next_reboot_time'] = status['last_boot_time'] + (reboot_interval_days * 24 * 3600)
                    
                    with open(STATUS_FILE, 'w', encoding='utf-8') as f:
                        json.dump(status, f, indent=4, ensure_ascii=False)
                    
                    logger.info('状态文件已更新')
                except Exception as e:
                    logger.error(f'更新状态文件失败: {e}')
            
            flash('配置保存成功！', 'success')
        else:
            flash('配置保存失败，请检查日志', 'error')
            
    except ValueError as e:
        flash(f'错误：请输入有效的数字值 - {str(e)}', 'error')
    except Exception as e:
        flash(f'错误：保存配置时发生异常 - {str(e)}', 'error')
        logger.error(f'保存配置时发生异常: {e}')
    
    return redirect(url_for('index'))

@app.route('/test-email', methods=['POST'])
def test_email():
    """测试邮件发送功能"""
    try:
        config = load_config()
        
        # 从配置中获取邮件设置
        email_config = config['email']
        recipients = email_config['recipients']
        
        if not recipients:
            return jsonify({
                'status': 'error',
                'message': '没有配置收件人邮箱'
            })
        
        # 导入email相关模块
        import smtplib
        from email.mime.multipart import MIMEMultipart
        from email.mime.text import MIMEText
        
        try:
            # 创建邮件对象
            msg = MIMEMultipart()
            msg['From'] = email_config['sender']
            msg['To'] = ', '.join(recipients)
            msg['Subject'] = '自动重启服务 - 测试邮件'
            
            # 添加邮件正文
            message = "这是一封来自自动重启服务的测试邮件。\n\n"
            message += f"当前配置:\n"
            message += f"- SMTP服务器: {email_config['smtp_server']}:{email_config['smtp_port']}\n"
            message += f"- 发件人: {email_config['sender']}\n"
            message += f"- 收件人: {', '.join(recipients)}\n"
            message += f"- 重启间隔: {config.get('reboot_interval_days', 15)}天\n"
            message += f"- 提前警告: {config.get('reboot_warning_hours', 24)}小时 + {config.get('reboot_warning_minutes', 30)}分钟\n\n"
            message += "如果您收到此邮件，说明邮件设置正确。"
            
            msg.attach(MIMEText(message, 'plain', 'utf-8'))
            
            # 连接SMTP服务器并发送邮件
            with smtplib.SMTP(email_config['smtp_server'], email_config['smtp_port']) as server:
                server.starttls()  # 启用TLS加密
                server.login(email_config['username'], email_config['password'])
                server.send_message(msg)
            
            logger.info(f"测试邮件已成功发送到 {', '.join(recipients)}")
            
            return jsonify({
                'status': 'success',
                'message': f'测试邮件已成功发送到 {len(recipients)} 个收件人，请检查您的邮箱'
            })
        except Exception as e:
            logger.error(f'邮件测试发送失败: {e}')
            return jsonify({
                'status': 'error',
                'message': f'发送邮件失败: {str(e)}'
            })
    except Exception as e:
        logger.error(f'邮件测试处理失败: {e}')
        return jsonify({
            'status': 'error',
            'message': f'测试失败: {str(e)}'
        })

@app.route('/status')
def status_api():
    """获取服务状态的API端点"""
    status = get_service_status()
    return jsonify(status)

if __name__ == '__main__':
    # 确保templates目录存在
    if not os.path.exists('templates'):
        os.makedirs('templates')
    
    # 确保static目录存在
    if not os.path.exists('static/css'):
        os.makedirs('static/css')
    
    # 启动Flask应用
    logger.info('启动Web配置界面...')
    app.run(host='0.0.0.0', port=5000, debug=True)