//#-hidden-code
//
//  See LICENSE folder for this template’s licensing information.
//
//  Abstract:
//  The Swift file containing the source code edited by the user of this playground book.
//

//画像を送り出すサーバー側

import PlaygroundSupport
import AudioToolbox
import Foundation
import Network
import UIKit

let page = PlaygroundPage.current

page.needsIndefiniteExecution = true

func vprint(_ str: String) {
   if let proxy1 = page.liveView as? PlaygroundRemoteLiveViewProxy {
       let message: PlaygroundValue = .string(str)
       proxy1.send(message)
   }
}

func recvPhoto() {
    //ビューに写真データの送信をリクエスト
    if let proxy1 = page.liveView as? PlaygroundRemoteLiveViewProxy {
        let message: PlaygroundValue = .string("GET-PHOTO")
        proxy1.send(message)
    }
}

//GET-PHOTOリクエスト後に送られるビューの写真を受信した場合の処理
let proxy2 = page.liveView as? PlaygroundRemoteLiveViewProxy
class pgListener: PlaygroundRemoteLiveViewProxyDelegate {
    func remoteLiveViewProxy(_ remoteLiveViewProxy: PlaygroundRemoteLiveViewProxy,received message: PlaygroundValue) {
        if case let .data(imageData) = message {
            photoImage = UIImage(data: imageData)!
            //vprint("写真を送信用にセットしました。")
        } else {
            //イメージ失敗
            let soundIdRing:SystemSoundID = 1006
            AudioServicesPlaySystemSound(soundIdRing)
        }
    }
    func remoteLiveViewProxyConnectionClosed(_ remoteLiveViewProxy: PlaygroundRemoteLiveViewProxy) {
    //コネクション切断時の処理
    }
}
let pglistener = pgListener()
proxy2?.delegate = pglistener
recvPhoto()
//#-end-hidden-code
/*: some text
 ##  🖼️1️⃣サーバー側
　このプログラムは、リスナーを起動して接続要求を待機します。\
　クライアント側から接続要求がありコネクションを開始したら、画像データを送信します。\
 サーバープログラムの実行順序を考えながら、プログラムを完成させてください。
 * Note:
 送信する写真は、写真をタップすると変更する事ができます。\
 写真を送信できるようになったら、他のクライアントプログラムにも送信できる事を確認してください。
 ---
 */

//写真のイメージデータを保持
private var photoImage = UIImage()
//ポート番号
private var port = NWEndpoint.Port(rawValue: 50000)!

// リスナーの起動
func startListener() {
    let listener = try! NWListener(using: .tcp, on: port)
    listener.newConnectionHandler = { newConnection in
        handleNewConnection(newConnection)
    }
    listener.start(queue: .main)
    vprint("リスナーを開始しました。")
}

// 新しい接続のハンドリング
func handleNewConnection(_ newConnection: NWConnection) {
    var remoteHost = ""
    switch(newConnection.endpoint) {
        case .hostPort(let host, _):
        let host = NWEndpoint.Host("\(host)")
            vprint("listener_\(host)からの接続がありました。")
            break
        default:
            break
    }
    let connection = newConnection
    connection.stateUpdateHandler = { newState in
    }
    //コネクション開始
    connection.start(queue: .main)
    //🖍️ここにイメージ送信をするための関数を呼びたす記述を書くと完成します。
    //解答例
    sendImageData(connection: connection)
}

// クライアントに画像データを送信する
func sendImageData(connection: NWConnection) {
    let imageData: Data = photoImage.jpegData(compressionQuality: 1)!
    connection.start(queue: .main)
    connection.send(content: imageData, completion: .contentProcessed { error in
        if let error = error {
            vprint("イメージの送信に失敗しました.: \(error.localizedDescription)")
        } else {
            vprint("イメージの送信に成功しました.")
        }
        connection.cancel()
    })
}
//
startListener()
