package main

import (
	"fmt"
	"os"
	"path/filepath"

	"gopkg.in/ini.v1"
	"hnyfkj.com.cn/rtu/linux/baseapp"
	"hnyfkj.com.cn/rtu/linux/sshd"
)

const MODULE_NAME = sshd.MODULE_NAME

type MQTTBroker struct {
	Address  string `ini:"BrokerAddress"` // 地址端口
	Username string `ini:"Username"`      // 用户名称
	Password string `ini:"Password"`      // 接入密码
}

type Config struct {
	MQTTSrv MQTTBroker `ini:"MQTTSrv"`
}

var (
	CfgServers = &Config{
		MQTTSrv: MQTTBroker{
			Address:  "tcp://8.136.98.49:61883",
			Username: "user",
			Password: "f335bf402c655ee5fd2b5300905124e",
		},
	}
	Version = "1.0.0.2"
)

func loadCfgServers() error {
	cfgFile := filepath.Join(baseapp.CFG_DIR, "sshd_cfg.ini")
	cfgIni, err := ini.Load(cfgFile)
	if err != nil {
		return err
	}

	if cfgIni.HasSection("MQTTSrv") {
		if err := cfgIni.Section("MQTTSrv").MapTo(&CfgServers.MQTTSrv); err != nil {
			return err
		}
	} else {
		return fmt.Errorf("配置文件\"%s\"缺少\"[MQTTSrv]\"节", cfgFile)
	}

	return nil
}

func main() {
	baseapp.SetOptDirs(true, true, false, false)
	baseapp.InitPath()
	sshdCfgFile, err := ensureSSHDConfig()
	if err != nil {
		fmt.Printf("[YFKJ_SSHD] ensure config failed: %v\n", err)
		os.Exit(1)
	}

	baseapp.WriteVersionFile(baseapp.EXEC_DIR, Version) //-> for 升级

	baseapp.InitLogger(sshdCfgFile)
	baseapp.SingleInstanceRun() // 异步非阻塞
	baseapp.Logger.Infof("程序版本: %s 构建时间: %s\n程序开始运行...",
		Version, baseapp.BuildTime)

	if err := loadCfgServers(); err != nil {
		baseapp.Logger.Warnf("[%s] 加载服务器配置项失败: %v!", MODULE_NAME, err)
	}

	devIMEI := baseapp.GetArgsParamStr("-devIMEI", "")
	success := sshd.ModuleInit(CfgServers.MQTTSrv.Address, CfgServers.MQTTSrv.Username, CfgServers.MQTTSrv.Password, devIMEI)
	if !success {
		return
	}

	<-baseapp.IsExit2()

	sshd.ModuleExit()
	baseapp.Logger.Info("程序退出")
	baseapp.ExitLogger() // 安全的关闭日志模块
	baseapp.SafeExit()   // 安全的关闭退出程序
}

const defaultSSHDCfg = `[Log]
; 日志级别: trace、debug、info、warn、error、fatal、panic
Level = info
; 输出目标: console(控制台)、file(文件)、all(控制台+文件)
Target = all
; 每个日志文件的最大大下, 以"MB"为单位
MaxFileSize = 5
; 保留的最大备份文件数量
MaxBackupFileCnts = 1

[MQTTSrv]
; 地址端口
BrokerAddress = tcp://8.136.98.49:61883
; 用户名称
Username = user
; 接入密码
Password = f335bf402c655ee5fd2b5300905124e
`

func ensureSSHDConfig() (string, error) {
	cfgFile := filepath.Join(
		baseapp.CFG_DIR,
		"sshd_cfg.ini",
	)

	if err := os.MkdirAll(
		baseapp.CFG_DIR,
		0755,
	); err != nil {
		return "", err
	}

	f, err := os.OpenFile(
		cfgFile,
		os.O_CREATE|os.O_EXCL|os.O_WRONLY,
		0644,
	)
	if err != nil {
		if os.IsExist(err) {
			return cfgFile, nil
		}
		return "", err
	}

	if _, err = f.WriteString(defaultSSHDCfg); err != nil {
		_ = f.Close()
		_ = os.Remove(cfgFile)
		return "", err
	}

	if err = f.Sync(); err != nil {
		_ = f.Close()
		_ = os.Remove(cfgFile)
		return "", err
	}

	if err = f.Close(); err != nil {
		_ = os.Remove(cfgFile)
		return "", err
	}

	return cfgFile, nil
}
