#!/usr/bin/env python3
"""Gitea 웹훅 + Jenkins CI/CD 완전 자동화 설정"""
import paramiko, time, sys, json

HOST = '101.79.17.164'; USER = 'root'; PASS = '1q2w3e!Q'
GITEA_USER = 'zio'; GITEA_PASS = 'Zio@Admin2026!'

client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(HOST, username=USER, password=PASS, timeout=15)
sftp = client.open_sftp()

def run(label, cmd, timeout=30):
    print(f'\n[{label}]')
    chan = client.get_transport().open_session()
    chan.set_combine_stderr(True)
    chan.exec_command(cmd)
    start = time.time()
    while not chan.exit_status_ready():
        if chan.recv_ready(): sys.stdout.buffer.write(chan.recv(4096)); sys.stdout.flush()
        if time.time() - start > timeout: break
        time.sleep(0.2)
    while chan.recv_ready(): sys.stdout.buffer.write(chan.recv(4096))
    sys.stdout.flush()
    rc = chan.recv_exit_status()
    print(f'exit={rc}'); return rc

# 1. Jenkins 초기 설정 스킵 & 보안 완화 (로컬 전용)
run('Jenkins 초기설정 스킵',
    'echo 2 > /var/lib/jenkins/jenkins.install.UpgradeWizard.state && '
    'chown jenkins:jenkins /var/lib/jenkins/jenkins.install.UpgradeWizard.state')

# Jenkins가 CSRF 없이 트리거 허용하도록 설정 (내부망 전용)
jenkins_config_groovy = """
import jenkins.model.*
import hudson.security.*

def instance = Jenkins.getInstance()

// CSRF 설정 완화 (내부망 전용)
instance.setCrumbIssuer(null)
instance.save()
println "CSRF disabled for internal CI/CD"
"""
with sftp.open('/var/lib/jenkins/init.groovy.d/disable_csrf.groovy', 'w') as f:
    f.write(jenkins_config_groovy)
run('권한 설정', 'chown -R jenkins:jenkins /var/lib/jenkins/init.groovy.d && systemctl restart jenkins && sleep 8 && systemctl is-active jenkins')

# 2. Jenkins 빌드 트리거 (CSRF 비활성화 후)
chan = client.get_transport().open_session()
chan.exec_command('cat /var/lib/jenkins/secrets/initialAdminPassword')
jenkins_pw = chan.makefile().read().decode().strip()
chan.recv_exit_status()

trigger_script = f"""#!/usr/bin/env python3
import urllib.request, base64, time

PW = '{jenkins_pw}'
cred = base64.b64encode(f'admin:{{PW}}'.encode()).decode()
headers = {{'Authorization': f'Basic {{cred}}'}}

for attempt in range(5):
    try:
        req = urllib.request.Request(
            'http://localhost:8080/job/zioinfo-web/build',
            data=b'', headers=headers)
        resp = urllib.request.urlopen(req, timeout=10)
        print(f'빌드 트리거 성공 HTTP {{resp.status}}')
        break
    except Exception as e:
        print(f'시도 {{attempt+1}}: {{e}}')
        time.sleep(3)
"""
with sftp.open('/tmp/trigger.py', 'w') as f:
    f.write(trigger_script)

run('Jenkins 빌드 트리거', 'python3 /tmp/trigger.py')

# 3. Gitea 웹훅 확인 / 재설정 (Jenkins 빌드 URL로)
run('Gitea 웹훅 목록 확인',
    'curl -s http://localhost:3000/api/v1/repos/zio/zioinfo-web/hooks '
    '-u "zio:Zio@Admin2026!" | python3 -c "import json,sys; '
    'hooks=json.load(sys.stdin); '
    '[print(h[chr(105)+chr(100)], h[chr(99)+chr(111)+chr(110)+chr(102)+chr(105)+chr(103)][chr(117)+chr(114)+chr(108)]) for h in hooks]"')

# 웹훅을 Jenkins 빌드 직접 트리거 URL로 교체
run('Gitea 웹훅 업데이트',
    f'curl -s -X DELETE http://localhost:3000/api/v1/repos/zio/zioinfo-web/hooks/1 '
    f'-u "{GITEA_USER}:{GITEA_PASS}" && '
    f'curl -s -X DELETE http://localhost:3000/api/v1/repos/zio/zioinfo-web/hooks/2 '
    f'-u "{GITEA_USER}:{GITEA_PASS}" && '
    f'curl -s -X POST http://localhost:3000/api/v1/repos/zio/zioinfo-web/hooks '
    f'-H "Content-Type: application/json" '
    f'-u "{GITEA_USER}:{GITEA_PASS}" '
    f'-d \'{{"type":"gitea","active":true,'
    f'"config":{{"url":"http://admin:{jenkins_pw}@localhost:8080/job/zioinfo-web/build",'
    f'"content_type":"json"}},'
    f'"events":["push"]}}\'  | '
    f'python3 -c "import json,sys; d=json.load(sys.stdin); print(chr(87)+chr(101)+chr(98)+chr(104)+chr(111)+chr(111)+chr(107)+chr(32)+chr(73)+chr(68)+chr(58), d.get(chr(105)+chr(100)))"')

sftp.close()
client.close()
print('\nCI/CD 설정 완료!')
print(f'Jenkins: http://{HOST}:8080  (초기PW: {jenkins_pw})')
print(f'Gitea:   http://{HOST}:3000  (zio / Zio@Admin2026!)')
print(f'홈페이지: http://{HOST}')
print(f'관리자:  http://{HOST}/admin')
