//#-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
let page = PlaygroundPage.current



let port = "50000" //ポート番号

private var connection : NWConnection!
page.needsIndefiniteExecution = true

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

func light_off() {
   if let proxy1 = page.liveView as? PlaygroundRemoteLiveViewProxy {
       let message: PlaygroundValue = .string("LIGHT-OFF")
       proxy1.send(message)
   }
}


func recv(connection: NWConnection) {
    //let semaphore = DispatchSemaphore(value: 0)
    // データ受信
    
    connection.receive(minimumIncompleteLength: 1,
                       maximumLength: 4096,
                       completion:{(data, context, flag, error) in
        if let error = error {
            vprint("\(#function): \(error.localizedDescription)")
            connection.cancel()
        } else {
            if let data = data, !data.isEmpty {
                // データをテキストに
                let text = String(data: data, encoding: .utf8)!
                vprint("[受信]\(text)\n")
                if (text == "ON") {
                    light_on()
                    let soundIdRing:SystemSoundID = 1012
                    AudioServicesPlaySystemSound(soundIdRing)
                } else if(text == "OFF") {
                    light_off()
                    let soundIdRing:SystemSoundID = 1003
                    AudioServicesPlaySystemSound(soundIdRing)
                }
                //次の受信待ちのための再帰呼び出し
                if(flag == false) {
                    recv(connection: connection)
                }
                //semaphore.signal()
            }
            else {
                vprint("receiveMessage data nil")
            }
        }
    })
}

//#-end-hidden-code
/*: some text
 ##  💡1️⃣サーバー側
　このプログラムは、リスナーを起動してクライアントからの接続要求を待ちます。接続要求があったら、コネクションを確立して、メッセージの受信を開始します。\
　このプログラムを実行した後で、クライアントプログラムから接続してください。
 * Important:
 このプログラムは変更する必要はありません。\
 接続するiPad同士は同じWi-Fi環境に接続している必要があります。
 ---
 * Note:
 クライアントからの接続要求を待つためのプログラムは、イベントを操作する事から、「イベントハンドラ」と呼ばれています。\
 このプログラムでは、「接続要求」というイベントが発生したら、相手のIPアドレスを取得して表示し、コネクションを開始するように操作（ハンドリング）しています。\
 vprint()は、ライブビューの文字エリアにメッセージを表示します。
 ---
 */

// 受信側リスナー開始
let myQueue  = DispatchQueue.global()

do {
    let listener = try NWListener(using: .tcp, on: 50000)
    listener.newConnectionHandler = { (newConnection) in
        // コネクト要求イベントのハンドリング
        var remoteHost = ""
        switch(newConnection.endpoint) {
            case .hostPort(let host, _):
                remoteHost = "\(host)"
                vprint("\(remoteHost)からの接続がありました\n")
            default:
                break
        }
        //コネクションを開始する。
        newConnection.start(queue: myQueue)
        //コネクションから受信する。
        recv(connection: newConnection)
    }
    vprint("リスナーを開始しました。\n")
    listener.start(queue: myQueue)
}
catch {
    vprint("\(error)")
}
