package app

import (
	"chain33-pai/models"
	"chain33-pai/pkg/setting"
	"fmt"
	"bytes"
	"log"
	"math/rand"
	"os"
	"os/exec"
	"strings"
	"sync"
	"time"
)

func GennerPort()(port,daemonPort int,err error){
	for{
		var flag bool
		var buf bytes.Buffer
		rand.Seed(time.Now().Unix())
		port=rand.Intn(65535)
		rand.Seed(time.Now().Unix())
		daemonPort=rand.Intn(55535)
		ss:=exec.Command(setting.Chain33Pai.SS,fmt.Sprint(port))
		ss.Stdout=&buf
		err=ss.Start()
		if err!=nil{
			log.Println(err)
			return

		}
		ss.Wait()
		if err!=nil{
				log.Println(err)
				return
		}

		//为空代表端口未被占用
		if buf.String()==""{
			log.Println(port)
			flag=true
		}
		ss=exec.Command(setting.Chain33Pai.SS,fmt.Sprint(daemonPort))
		ss.Stdout=&buf
		err=ss.Start()
		if err!=nil{
			log.Println(err)
			return
		}
		ss.Wait()
		if err!=nil{
			log.Println(err)
			return
		}

		//守护端口和通信端口都未被占用的情况下返回
		if buf.String()==""&&flag{
			log.Println(port)
			//fmt.Println("finish")
			return
		}
	}
}

var mu sync.Mutex
func AppendKeyPair(keyPair string){
	mu.Lock()
	defer mu.Unlock()
	f,err:=os.OpenFile(fmt.Sprintf("%s/authorized_keys",setting.Chain33Pai.SSH),os.O_WRONLY|os.O_APPEND,0600)
	defer f.Close()
	if err!=nil{
		log.Println(err)
		return
	}
	f.WriteString(keyPair)
}
func Preprocessing(){//判断密钥对是否存在,存在则删除
	_, err := os.Stat(setting.Chain33Pai.SSH)
	if err == nil || os.IsExist(err){
		err=os.RemoveAll(setting.Chain33Pai.SSH)
		fmt.Println(err)
	}
}

func reKeygen(){
	Preprocessing()
	ssh_keygen:=exec.Command(setting.Chain33Pai.Keygen)
	ssh_keygen.Start()
	ssh_keygen.Wait()
	f,_:=os.OpenFile("authorized_keys",os.O_CREATE,0600)
	f.Close()

}
func CleanUp(){
	var buff bytes.Buffer
	netstat:=exec.Command(setting.Chain33Pai.NetStat)
	netstat.Stdout=&buff
	idSelector:=strings.Split(buff.String(),"\n")
	if len(idSelector)==0{//没有映射端口存在，即没有需要处理的反馈
		reKeygen()//清空authorized_keys
		models.DropFeedBack()//清空数据库记录
		return
	}
	for _,v:=range idSelector{
		if models.IsComplete(v){
			models.DelFeedBack(v)
		}
	}
}

func CornClean(ticker *time.Ticker){
	for{
		select {
		case <-ticker.C:
			CleanUp()
		}
	}
}