package main

import (
	"io"
	"log"
	"net"
	"os"
	"strings"

	"gopkg.in/ini.v1"
)

func readConfig() (string, string) {
	cfg, err := ini.Load("config.conf")
	if err != nil {
		log.Fatalf("无法读取配置文件: %v", err)
		os.Exit(1)
	}
	section := cfg.Section("url")

	minerPort := strings.Trim(section.Key("in").String(), `""`)
	minerPoolAddr := strings.Trim(section.Key("out").String(), `""`)

	return minerPort, minerPoolAddr
}

var minerPort, minerPoolAddr = readConfig()

// 处理矿机请求的函数
func handleMinerConnection(minerConn net.Conn) {
	defer minerConn.Close()
	log.Println("有矿机接入")
	// 连接到矿池
	poolConn, err := net.Dial("tcp", minerPoolAddr)
	if err != nil {
		log.Printf("无法连接到矿池: %v", err)
		return
	}
	defer poolConn.Close()

	// 启动两个 goroutine：一个从矿机接收数据并转发到矿池，另一个从矿池接收数据并转发回矿机
	go transferData(minerConn, poolConn)
	go transferData(poolConn, minerConn)

	// 保持服务运行，直到矿机或矿池关闭连接
	select {}
}

// 数据转发函数：从源连接读取数据并写入到目标连接
func transferData(src net.Conn, dest net.Conn) {
	_, err := io.Copy(dest, src)
	if err != nil {
		log.Printf("数据转发失败: %v", err)
	}
}

func main() {
	// 设置代理服务监听端口
	listener, err := net.Listen("tcp", minerPort)
	if err != nil {
		log.Fatalf("无法启动监听服务: %v", err)
		os.Exit(1)
	}
	defer listener.Close()

	log.Printf("代理服务启动，监听端口 %s\n", minerPort)

	// 不断接收来自矿机的连接
	for {
		// 接受矿机连接
		minerConn, err := listener.Accept()
		if err != nil {
			log.Printf("接受连接失败: %v", err)
			continue
		}

		// 为每个矿机连接启动一个新的 goroutine 来处理
		go handleMinerConnection(minerConn)
	}
}
