package main

import (
	"log"
	"net/http"
	"github.com/gorilla/websocket"
	"fmt"
)

var clients = make(map[*websocket.Conn]bool) // 连接客户端
var broadcast = make(chan Message, 100)           // 广播频道

// 配置upgrader
var upgrader = websocket.Upgrader{
	//允许跨域
	CheckOrigin: func(r *http.Request) bool {
		return true
	},
}

// 定义消息结构体
type Message struct {
	Email    string `json:"email"`
	Username string `json:"username"`
	Message  string `json:"message"`
}

func main() {
	// 创建一个简单的文件服务器
	fs := http.FileServer(http.Dir("../public"))
	http.Handle("/", fs)

	// 配置websocket路由
	http.HandleFunc("/ws", handleConnections)

	// 开始收听传入的聊天信息
	go handleMessages()

	// 在本地主机端口8000上启动服务器并记录所有错误
	log.Println("http server started on :8000")
	err := http.ListenAndServe(":8000", nil)
	if err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}

func handleConnections(w http.ResponseWriter, r *http.Request) {
	// 完成握手(Upgrade initial GET request to a websocket)
	ws, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Fatal(err)
	}
	// 确保在函数返回时关闭连接
	defer ws.Close()

	// 提示下机
	defer fmt.Printf("——%v下机了——", ws.RemoteAddr())

	// 注册我们的新客户端
	clients[ws] = true

	// 输出ip
	fmt.Println("当前登录用户:", ws.RemoteAddr())

	for {
		var msg Message
		// 以JSON的形式读取新消息并将其映射到消息对象
		err := ws.ReadJSON(&msg)

		// 输出clients
		//fmt.Println(clients)


		if err != nil {
			log.Printf("error: %v", err)
			delete(clients, ws)
			break
		}
		// Send the newly received message to the broadcast channel
		broadcast <- msg
	}
}

func handleMessages() {
	for {
		// 从广播频道获取下一条消息
		msg := <-broadcast

		fmt.Println("======总共发送的客户端======")

		// 发送到当前连接的每个客户端
		for client := range clients {
			err := client.WriteJSON(msg)

			//输出推送到的客户端的ip
			fmt.Println(client.RemoteAddr())

			if err != nil {
				log.Printf("error: %v", err)
				client.Close()
				delete(clients, client)
			}
		}

		fmt.Println("======总共发送的客户端======")

	}
}