package main

import (
	"fmt"
	"io"
	"log"
	"net"
	"os"
	"strings"
	"sync"
	"time"
)

// 定义一个*data类型切片
var dSlice []*data

func main() {
	// 1. 从控制台读取要记录的时区服务器地址
	// 2. 启动一个goroutine，每隔一秒钟向服务器发送一个请求，获取当前时间
	// 3. 将服务器返回的时间输出到控制台

	var wg sync.WaitGroup
	wg.Add(len(os.Args[1:]))
	// 获取服务器地址
	// Tokyo=localhost:8020 London=localhost:8030
	var server = make(map[int][]string)
	for i, v := range os.Args[1:] {
		// 处理输入
		server[i] = strings.Split(v, "=")
	}
	// 启动时钟
	for i, server := range server {
		// 创建一个data类型的指针
		dSlice = append(dSlice, new(data))
		// 启动时钟
		go clock(server[1], dSlice[i], &wg)
	}
	// 输出
	// $ go run 8.1.go China=localhost:8000 Tokyo=localhost:8010
	//====================================
	//Tokyo localhost:8010 13:55:32
	//China localhost:8000 12:55:32

	// 输出前等待1s, 保证数据已经接收到并且写入到data类型的指针中
	time.Sleep(1 * time.Second)
	for {
		fmt.Println("====================================")
		for i, s := range server {
			go output(s, dSlice[i])
		}
		time.Sleep(1 * time.Second)
	}
	// 尽管上面的死循环会阻塞主协程
	// 但是还是写上吧
	// 调试也方便
	wg.Wait()
}
func output(ser []string, data *data) {
	fmt.Println(ser[0], ser[1], data)
}

// data 类型
type data string

// 输出*data的时候，直接输出解引用data的值
func (d *data) String() string {
	return string(*d)
}

// 实现Writer接口, 用于将数据写入到data类型的指针中
func (d *data) Write(p []byte) (n int, err error) {
	// 写入数据
	*d = data(p)
	//fmt.Println(d)
	return len(p), nil
}

// 编写监听多个服务器的时钟函数
func clock(server string, data *data, wg *sync.WaitGroup) {
	defer wg.Done()
	//fmt.Println(server)
	conn, err := net.Dial("tcp", server)
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()
	mustCopy(data, conn)

}
func mustCopy(dst io.Writer, src io.Reader) {
	if _, err := io.Copy(dst, src); err != nil {
		log.Fatalln(err)
	}
}
