//#-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 viewPhoto(_ image: UIImage) {
   if let proxy1 = page.liveView as? PlaygroundRemoteLiveViewProxy {
       let message: PlaygroundValue = .data(image.jpegData(compressionQuality: 1)!)
       proxy1.send(message)
       let soundIdRing:SystemSoundID = 1111
       AudioServicesPlaySystemSound(soundIdRing)
   }
}
//#-end-hidden-code
/*: some text
 ##  🖼️2️⃣クライアント側
　このプログラムは、サーバープロラムに接続要求をして、接続が確立したら画像データを受信するクライアントプログラムです。\
　１回だけ写真を受信するように作ってありますので、再度受信する場合には、プログラムを終了して、もう一度［コードを実行］ボタンで実行してください。

 * Note:
 別のiPadでサーバープログラムを実行中に実行してください。\
 接続するサーバーのIPアドレスを確認して、プログラムの内容を変更してから実行してください。
 ---
 */


//ネットワークコネクション
private var connection: NWConnection?
//受信中のイメージデータ保存用
private var receivedImageData: Data?
//🖍️サーバーのIPアドレス
private var host = NWEndpoint.Host("192.168.0.62")
//ポート番号
private var port = NWEndpoint.Port(rawValue: 50000)!

//コネクションを開始する手続き
connection = NWConnection(host: host, port: port, using: .tcp)
connection?.stateUpdateHandler = { newState in
    //コネクションの状態変化で呼び出すハンドラ
    handleConnectionState(newState)
}
connection?.start(queue: .main)


// 接続の状態変更ハンドリング
func handleConnectionState(_ newState: NWConnection.State) {
    // コネクト要求イベントのハンドリング
    switch newState {
    case .ready:
        //コネクションが確立したとき
        vprint("コネクションが確立しました。")
        //🖍️ここでイメージを受信するための関数を呼び出してください。
        //解答例
        receiveImageData()
    case .cancelled:
        vprint("recv_コネクションがキャンセルされました。")
    case .failed(let error):
        vprint("recv_コネクションに失敗しました。: \(error.localizedDescription)")
    default:
        break
    }
}

// 画像データの受信処理
func receiveImageData() {
    let bufferSize = 4096
    connection?.receive(minimumIncompleteLength: 1, maximumLength: bufferSize) { data, _, isComplete, error in
        //guard let self = self else { return }
        
        if let data = data, !data.isEmpty {
            //受信したデータが空でなければ蓄積
            if receivedImageData == nil {
                receivedImageData = data
            } else {
                receivedImageData?.append(data)
            }
        }
        if isComplete || error != nil {
            //受信が終了した場合の処理
            imageReceived()
        } else {
            //終了していなければ再度受信をする
            receiveImageData()
        }
    }
}

// 画像データの受信が完了した場合の処理
func imageReceived() {
    if let imageData = receivedImageData {
        guard let newImage = UIImage(data: imageData)
        else {
            return
        }
        vprint("画像が受信できました。")
        //右側のビューに写真を表示
        viewPhoto(newImage)
    }
    //接続を終了
    connection?.cancel()
}
