//
//  SNIViewController.swift
//  DNSResolverSwiftDemo
//
//  Created by issuser on 2025/9/2.
//

import UIKit
import Foundation

/**
 *  本示例仅用于演示HTTPS SNI场景下的处理方式。
 *  Demo为实现统一的NSURLProtocol，统一在`CFHTTPDNSProtocol`拦截请求后进行HTTPDNS域名解析。
 *  由于在SNI场景下，网络请求必须基于底层CFNetwork完成，建议不要拦截非SNI场景的网络请求，尽可能走上层网络库发送网络请求。
 *  iOS14原生方案：https://help.aliyun.com/document_detail/203723.html
 */
class SNIViewController: UIViewController {

    private var resultTextView: UITextView!

    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.backgroundColor = .white
        title = "SNI场景"
        
        createUI()
        creatData()
    }

    private func creatData() {
        // 注：在AppDelegate中预解析该域名
        let domain = "www.douyin.com"
//        let domain = "m.jtexpress.com.cn"
        
        let urlString = "https://\(domain)"
        guard let url = URL(string: urlString) else { return }
        
        var request = URLRequest(url: url)
        
        /*
         *  NSURLSession加载资源场景
         */
        let configuration = URLSessionConfiguration.default
        
        // 假设 DNSResolver 是一个单例类，提供同步获取 IP 的方法
        if let ip = DNSResolver.share().getIpsByCache(withDomain: domain, andExpiredIPEnabled: true).first {
            configuration.protocolClasses = [CFHTTPDNSHTTPProtocol.self]
        }
        
        let session = URLSession(configuration: configuration, delegate: self, delegateQueue: .main)
        let task = session.dataTask(with: request)
        task.resume()
    }

    private func createUI() {
        resultTextView = UITextView(frame: CGRect(x: 0, y: 200, width: UIScreen.main.bounds.width, height: 200))
        resultTextView.backgroundColor = UIColor.lightGray
        view.addSubview(resultTextView)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

// MARK: - URLSession Data Delegate
extension SNIViewController: URLSessionDataDelegate, URLSessionTaskDelegate {

    func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
        if let str = String(data: data, encoding: .utf8) {
            print("data: \(str)")
            resultTextView.text = str
        }
        session.finishTasksAndInvalidate()
    }

    func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) {
        print("response: \(response)")
        completionHandler(.allow)
    }

    func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
        if let error = error {
            print("error: \(error.localizedDescription)")
        } else {
            print("complete")
        }
    }
}

