"""자료실의 실제 HTTPS 조회·다운로드·격리 설정을 확인한다."""
import hashlib
import json
import sys
import urllib.error
import urllib.request
from pathlib import Path


def verify(base):
    entries = json.loads((Path(__file__).resolve().parents[1] / 'public_materials' / 'manifest.json').read_text(encoding='utf-8'))['files']
    checks = []
    def get(path, expected=200):
        try:
            response = urllib.request.urlopen(base.rstrip('/') + path, timeout=30)
        except urllib.error.HTTPError as error:
            response = error
        with response:
            body = response.read()
            assert response.code == expected, (path, response.code)
            checks.append({'path': path, 'status': response.code})
            return body, response.headers
    assert b'/materials/' in get('/')[0]
    assert '프로젝트 자료실'.encode() in get('/materials/')[0]
    for kind in ('code', 'text', 'csv', 'image', 'map'):
        entry = next(e for e in entries if e['kind'] == kind)
        assert entry['path'].encode() in get('/materials/file/' + entry['id'])[0]
        body, headers = get('/materials/download/' + entry['id'])
        assert 'attachment' in headers['Content-Disposition']
        assert hashlib.sha256(body).hexdigest() == entry['sha256']
        if kind == 'map':
            body, headers = get('/materials/preview/' + entry['id'])
            assert hashlib.sha256(body).hexdigest() == entry['sha256']
            assert 'sandbox allow-scripts;' in headers['Content-Security-Policy']
            assert 'allow-same-origin' not in headers['Content-Security-Policy']
            assert b'&lt;html' in get('/materials/file/' + entry['id'] + '?view=source')[0]
        if kind == 'image':
            assert get('/materials/image/' + entry['id'])[1]['Content-Type'].startswith('image/png')
    get('/materials/download/.env', 404)
    get('/materials/file/' + 'f' * 20, 404)
    get('/materials/?folder=..', 404)
    return {'base': base, 'files': len(entries), 'checks': checks}


if __name__ == '__main__':
    result = verify(sys.argv[1] if len(sys.argv) > 1 else 'http://127.0.0.1:5000')
    if len(sys.argv) > 2:
        Path(sys.argv[2]).write_text(json.dumps(result, ensure_ascii=False, indent=2), encoding='utf-8')
    print(json.dumps(result, ensure_ascii=False, indent=2))
