import paramiko

client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect('152.136.232.83', port=22, username='root', password='Jianhua105', timeout=10)

def run(cmd):
    print(f"\n>>> {cmd[:120]}")
    stdin, stdout, stderr = client.exec_command(cmd, timeout=20)
    out = stdout.read().decode('utf-8', errors='replace').strip()
    err = stderr.read().decode('utf-8', errors='replace').strip()
    if out: print(out[-600:])
    if err: print(f"ERR: {err[-200:]}")
    return out

# Backup
run("cp /www/wwwroot/ipzhinengti/server.js /www/wwwroot/ipzhinengti/server.js.bak.update")
run("cp /www/wwwroot/ipzhinengti/public/admin.html /www/wwwroot/ipzhinengti/public/admin.html.bak.update")

# === Patch 1: server.js - add UPDATE_COS keys to publicKeys and compute update_url ===
patch_server = r'''const fs = require('fs');
const filePath = '/www/wwwroot/ipzhinengti/server.js';
let content = fs.readFileSync(filePath, 'utf-8');

if (content.includes('UPDATE_COS_BUCKET')) {
    console.log('SKIP: already patched');
    process.exit(0);
}

// 1. Add UPDATE_COS keys to publicKeys array
const marker1 = "        'cloud_beauty_enabled'";
const replacement1 = marker1 + ",\n        'UPDATE_COS_BUCKET',\n        'UPDATE_COS_REGION',\n        'UPDATE_COS_PATH'";
content = content.replace(marker1, replacement1);

// 2. Replace the res.json to add update_url computation
const marker2 = "res.json({ success: true, config })";
const replacement2 = `const cosBucket = config.UPDATE_COS_BUCKET || ''
            const cosRegion = config.UPDATE_COS_REGION || ''
            const updatePath = config.UPDATE_COS_PATH || 'updates'
            let updateUrl = ''
            if (cosBucket && cosRegion) {
                updateUrl = 'https://' + cosBucket + '.cos.' + cosRegion + '.myqcloud.com/' + updatePath
            }
            res.json({ success: true, config, update_url: updateUrl })`;
content = content.replace(marker2, replacement2);

fs.writeFileSync(filePath, content, 'utf-8');
console.log('OK: patched server.js');
'''

sftp = client.open_sftp()
with sftp.open('/tmp/patch_server.js', 'w') as f:
    f.write(patch_server)
sftp.close()

run("node /tmp/patch_server.js")
run("node --check /www/wwwroot/ipzhinengti/server.js 2>&1")

# === Patch 2: admin.html - add UPDATE_COS config section ===
patch_admin = r'''const fs = require('fs');
const filePath = '/www/wwwroot/ipzhinengti/public/admin.html';
let content = fs.readFileSync(filePath, 'utf-8');

if (content.includes('UPDATE_COS_BUCKET')) {
    console.log('SKIP: already patched');
    process.exit(0);
}

// 1. Add to CONFIG_KEYS array
const keysMarker = "'cloud_beauty_enabled'";
content = content.replace(keysMarker, keysMarker + ", 'UPDATE_COS_BUCKET', 'UPDATE_COS_REGION', 'UPDATE_COS_PATH'");

// 2. Add save values
const saveMarker = "cloud_beauty_enabled: document.getElementById('cfg_cloud_beauty_enabled').checked ? 'true' : 'false',";
const saveReplacement = saveMarker + "\n                        UPDATE_COS_BUCKET: document.getElementById('cfg_UPDATE_COS_BUCKET').value,\n                        UPDATE_COS_REGION: document.getElementById('cfg_UPDATE_COS_REGION').value,\n                        UPDATE_COS_PATH: document.getElementById('cfg_UPDATE_COS_PATH').value,";
content = content.replace(saveMarker, saveReplacement);

// 3. Add HTML section after cloud_beauty section
const htmlMarker = "document.getElementById('cfg_cloud_beauty_enabled').checked = config.cloud_beauty_enabled === 'true';";
const htmlSection = htmlMarker + `
            document.getElementById('cfg_UPDATE_COS_BUCKET').value = config.UPDATE_COS_BUCKET || '';
            document.getElementById('cfg_UPDATE_COS_REGION').value = config.UPDATE_COS_REGION || '';
            document.getElementById('cfg_UPDATE_COS_PATH').value = config.UPDATE_COS_PATH || '';`;
content = content.replace(htmlMarker, htmlSection);

// 4. Add form HTML - find the closing tag after cloud_beauty section
const formMarker = "<label>\\u542f\\u7528\\u4e91\\u7f8e\\u989c</label>";
const formSection = formMarker + `</div>
                    </div>
                    <h3 style="grid-column:1/-1;margin:15px 0 8px;padding-bottom:8px;border-bottom:1px solid #e2e8f0;">\\u81ea\\u52a8\\u66f4\\u65b0 COS \\u914d\\u7f6e</h3>
                    <div class="form-group"><label>\\u66f4\\u65b0\\u6876\\u540d</label><input type="text" id="cfg_UPDATE_COS_BUCKET" placeholder="xiazaigengxin-1417293730"></div>
                    <div class="form-group"><label>\\u5730\\u57df</label><input type="text" id="cfg_UPDATE_COS_REGION" placeholder="ap-guangzhou"></div>
                    <div class="form-group"><label>\\u66f4\\u65b0\\u8def\\u5f84</label><input type="text" id="cfg_UPDATE_COS_PATH" placeholder="updates"></div>
                </div>
            </div>
        </div>
    </div>
</body>
</html>`;
// Actually, let's find a better insertion point - the last form-group before save button
// Simpler: just append before the save button div

fs.writeFileSync(filePath, content, 'utf-8');
console.log('OK: patched admin.html');
'''

# Actually the admin.html patch is complex, let me use a simpler approach
# Just add the form fields after the cloud_beauty section
patch_admin2 = r'''const fs = require('fs');
const filePath = '/www/wwwroot/ipzhinengti/public/admin.html';
let content = fs.readFileSync(filePath, 'utf-8');

if (content.includes('UPDATE_COS_BUCKET')) {
    console.log('SKIP: already patched');
    process.exit(0);
}

// 1. Add to CONFIG_KEYS
content = content.replace(
    "'cloud_beauty_enabled'",
    "'cloud_beauty_enabled', 'UPDATE_COS_BUCKET', 'UPDATE_COS_REGION', 'UPDATE_COS_PATH'"
);

// 2. Add save values after cloud_beauty_enabled save line
content = content.replace(
    "cloud_beauty_enabled: document.getElementById('cfg_cloud_beauty_enabled').checked ? 'true' : 'false',",
    `cloud_beauty_enabled: document.getElementById('cfg_cloud_beauty_enabled').checked ? 'true' : 'false',
                        UPDATE_COS_BUCKET: document.getElementById('cfg_UPDATE_COS_BUCKET').value,
                        UPDATE_COS_REGION: document.getElementById('cfg_UPDATE_COS_REGION').value,
                        UPDATE_COS_PATH: document.getElementById('cfg_UPDATE_COS_PATH').value,`
);

// 3. Add load values
content = content.replace(
    "document.getElementById('cfg_cloud_beauty_enabled').checked = config.cloud_beauty_enabled === 'true';",
    `document.getElementById('cfg_cloud_beauty_enabled').checked = config.cloud_beauty_enabled === 'true';
            document.getElementById('cfg_UPDATE_COS_BUCKET').value = config.UPDATE_COS_BUCKET || '';
            document.getElementById('cfg_UPDATE_COS_REGION').value = config.UPDATE_COS_REGION || '';
            document.getElementById('cfg_UPDATE_COS_PATH').value = config.UPDATE_COS_PATH || '';`
);

// 4. Add HTML form fields - insert before the save button
// Find the save button and insert before it
const saveBtnPattern = '<button onclick="saveSystemConfig()"';
const insertHTML = `<div style="grid-column:1/-1;margin:15px 0 8px;padding-bottom:8px;border-bottom:1px solid #e2e8f0;font-weight:bold;">\u81ea\u52a8\u66f4\u65b0 COS \u914d\u7f6e</div>
                        <div class="form-group"><label>\u66f4\u65b0\u6876\u540d</label><input type="text" id="cfg_UPDATE_COS_BUCKET" placeholder="xiazaigengxin-1417293730"></div>
                        <div class="form-group"><label>\u5730\u57df</label><input type="text" id="cfg_UPDATE_COS_REGION" placeholder="ap-guangzhou"></div>
                        <div class="form-group"><label>\u66f4\u65b0\u8def\u5f84</label><input type="text" id="cfg_UPDATE_COS_PATH" placeholder="updates"></div>
                    `;
content = content.replace(saveBtnPattern, insertHTML + '\n                        ' + saveBtnPattern);

fs.writeFileSync(filePath, content, 'utf-8');
console.log('OK: patched admin.html');
'''

sftp = client.open_sftp()
with sftp.open('/tmp/patch_admin2.js', 'w') as f:
    f.write(patch_admin2)
sftp.close()

run("node /tmp/patch_admin2.js")

# === Insert UPDATE_COS config into database ===
insert_db = r'''const sqlite3 = require('sqlite3');
const path = require('path');
const dbPath = path.join('/www/wwwroot/ipzhinengti', 'data', 'database.db');
console.log('DB path:', dbPath);
const db = new sqlite3.Database(dbPath);

const configs = [
    ['UPDATE_COS_BUCKET', 'xiazaigengxin-1417293730'],
    ['UPDATE_COS_REGION', 'ap-guangzhou'],
    ['UPDATE_COS_PATH', 'updates']
];

let done = 0;
configs.forEach(([key, value]) => {
    db.run(
        'INSERT OR REPLACE INTO system_config (config_key, config_value) VALUES (?, ?)',
        [key, value],
        (err) => {
            if (err) console.log('ERR:', key, err.message);
            else console.log('OK:', key, '=', value);
            done++;
            if (done === configs.length) {
                db.close();
                console.log('ALL DONE');
            }
        }
    );
});
'''

sftp = client.open_sftp()
with sftp.open('/tmp/insert_config.js', 'w') as f:
    f.write(insert_db)
sftp.close()

run("node /tmp/insert_config.js")

# Restart user-server
run("pm2 restart user-server 2>&1")
run("sleep 3 && pm2 list")

# Test endpoint
run("curl -s http://localhost:3002/api/system/config/public")

client.close()
print("\n=== ALL PATCHED ===")
