/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package main

import (
	// "flag"
	"fmt"
	"net"
	"net/http"
	_ "net/http/pprof"
	"os"
	"os/signal"
	"sync/atomic"
	"syscall"
	"time"
)

import (
	getty "github.com/apache/dubbo-getty"
	"github.com/dubbogo/gost/net"
	"github.com/dubbogo/gost/time"
)

const (
	pprofPath = "/debug/pprof/"
)

const (
	WritePkgTimeout = 1e9
	WritePkgASAP    = 0e9
)

var (
	connectedClient   EchoClient
	unconnectedClient EchoClient
)

////////////////////////////////////////////////////////////////////
// main
////////////////////////////////////////////////////////////////////

func main() {
	initConf()

	initProfiling()

	initClient()
	log.Infof("%s starts successfull!", conf.AppName)

	go test()

	initSignal()
}

func initProfiling() {
	var addr string

	addr = gxnet.HostAddress(conf.LocalHost, conf.ProfilePort)
	log.Infof("App Profiling startup on address{%v}", addr+pprofPath)
	go func() {
		log.Info(http.ListenAndServe(addr, nil))
	}()
}

func newSession(session getty.Session) error {
	var (
		ok          bool
		udpConn     *net.UDPConn
		gettyClient getty.Client
		client      *EchoClient
		sessionName string
	)

	if gettyClient, ok = session.EndPoint().(getty.Client); !ok {
		panic(fmt.Sprintf("the endpoint type of session{%#v} is not getty.Client", session))
	}

	switch gettyClient {
	case connectedClient.gettyClient:
		client = &connectedClient
		sessionName = "connected-" + conf.GettySessionParam.SessionName

	case unconnectedClient.gettyClient:
		client = &unconnectedClient
		sessionName = "unconnected-" + conf.GettySessionParam.SessionName

	default:
		panic(fmt.Sprintf("illegal session{%#v} endpoint", session))
	}

	if conf.GettySessionParam.CompressEncoding {
		session.SetCompressType(getty.CompressZip)
	}

	if udpConn, ok = session.Conn().(*net.UDPConn); !ok {
		panic(fmt.Sprintf("%s, session.conn{%#v} is not udp connection\n", session.Stat(), session.Conn()))
	}

	udpConn.SetReadBuffer(conf.GettySessionParam.UdpRBufSize)
	udpConn.SetWriteBuffer(conf.GettySessionParam.UdpWBufSize)

	session.SetName(sessionName)
	session.SetMaxMsgLen(conf.GettySessionParam.MaxMsgLen)
	session.SetPkgHandler(echoPkgHandler)
	session.SetEventListener(newEchoMessageHandler(client))
	session.SetReadTimeout(conf.GettySessionParam.udpReadTimeout)
	session.SetWriteTimeout(conf.GettySessionParam.udpWriteTimeout)
	session.SetCronPeriod((int)(conf.heartbeatPeriod.Nanoseconds() / 1e6))
	session.SetWaitTime(conf.GettySessionParam.waitTimeout)
	log.Debugf("client new session:%s", session.Stat())

	return nil
}

func initClient() {
	unconnectedClient.gettyClient = getty.NewUDPEndPoint(
		getty.WithLocalAddress(gxnet.HostAddress(net.IPv4zero.String(), 0)),
	)
	unconnectedClient.gettyClient.RunEventLoop(newSession)
	unconnectedClient.serverAddr = net.UDPAddr{IP: net.ParseIP(conf.ServerHost), Port: conf.ServerPort}

	connectedClient.gettyClient = getty.NewUDPClient(
		getty.WithServerAddress(gxnet.HostAddress(conf.ServerHost, conf.ServerPort)),
		getty.WithConnectionNumber((int)(conf.ConnectionNum)),
	)
	connectedClient.gettyClient.RunEventLoop(newSession)
}

func uninitClient() {
	connectedClient.close()
	unconnectedClient.close()
}

func initSignal() {
	// signal.Notify的ch信道是阻塞的(signal.Notify不会阻塞发送信号), 需要设置缓冲
	signals := make(chan os.Signal, 1)
	// It is not possible to block SIGKILL or syscall.SIGSTOP
	signal.Notify(signals, os.Interrupt, os.Kill, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
	for {
		sig := <-signals
		log.Info("get signal %s", sig.String())
		switch sig {
		case syscall.SIGHUP:
		// reload()
		default:
			go time.AfterFunc(conf.failFastTimeout, func() {
				// log.Warn("app exit now by force...")
				// os.Exit(1)
				log.Info("app exit now by force...")
			})

			// 要么fastFailTimeout时间内执行完毕下面的逻辑然后程序退出，要么执行上面的超时函数程序强行退出
			uninitClient()
			// fmt.Println("app exit now...")
			log.Info("app exit now...")
			return
		}
	}
}

func echo(client *EchoClient) {
	var (
		err error
		pkg EchoPackage
		ctx getty.UDPContext
	)

	pkg.H.Magic = echoPkgMagic
	pkg.H.LogID = (uint32)(src.Int63())
	pkg.H.Sequence = atomic.AddUint32(&reqID, 1)
	// pkg.H.ServiceID = 0
	pkg.H.Command = echoCmd
	pkg.B = conf.EchoString
	pkg.H.Len = (uint16)(len(pkg.B)) + 1

	ctx.Pkg = &pkg
	ctx.PeerAddr = &(client.serverAddr)

	if session := client.selectSession(); session != nil {
		// err := session.WritePkg(ctx, WritePkgTimeout)
		_, _, err = session.WritePkg(ctx, WritePkgASAP)
		if err != nil {
			log.Warnf("session.WritePkg(session{%s}, UDPContext{%#v}) = error{%v}", session.Stat(), ctx, err)
			session.Close()
			client.removeSession(session)
		}
	}
}

func testEchoClient(client *EchoClient) {
	var (
		cost    int64
		counter gxtime.CountWatch
	)

	for {
		if client.isAvailable() {
			break
		}
		time.Sleep(3e9)
	}

	counter.Start()
	for i := 0; i < conf.EchoTimes; i++ {
		echo(client)
	}
	cost = counter.Count()
	log.Infof("after loop %d times, echo cost %d ms", conf.EchoTimes, cost/1e6)
}

func test() {
	testEchoClient(&unconnectedClient)
	testEchoClient(&connectedClient)
}
