/*
** Job Arranger for ZABBIX
** Copyright (C) 2025 Daiwa Institute of Research Ltd. All Rights Reserved.
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
**/

package main

import (
	"fmt"
	"os"
	"runtime/debug"

	clientcommon "jobarranger2/src/jobarg_server/managers/icon_exec_manager/workers/common"
	"jobarranger2/src/libs/golibs/common"
	"jobarranger2/src/libs/golibs/utils"
)

var (
	conn *common.NetConnection
)

type resultData struct {
	Result      int      `json:"result"`
	HostJobList []uint64 `json:"host_job_list"`
}

// Start job icon operation
func checkJobClient() (int, error) {

	var (
		data          common.EventData
		inputData     common.CheckProcess
		executionData common.IconExecutionProcessData

		tcpMessage common.TCPMessage
		resultData resultData

		agentVersion, port int
		ip, hostName       string
		err                error
	)

	executionData, err = clientcommon.GetIconExecData()
	if err != nil {
		return common.JA_JOBRESULT_SUCCEED, err
	}

	err = utils.Convert(executionData.CheckProcessData, &inputData)
	if err != nil {
		return common.JA_JOBRESULT_SUCCEED, fmt.Errorf("failed to convert Data : %w", err)
	}

	if inputData.HostResult.IP == "" || inputData.HostResult.Hostname == "" {
		return common.JA_JOBRESULT_SUCCEED, fmt.Errorf("invalid checkjob execution context: ip or hostname is is missing")
	}
	ip = inputData.HostResult.IP
	port = inputData.HostResult.Port
	hostName = inputData.HostResult.Hostname

	// prepare agent json data and next process data
	data.Event.Name = common.EventAgentJobCheck
	data.Event.UniqueKey = common.GetUniqueKey(common.IconExecManagerProcess)
	data.NextProcess.Name = common.AgentManagerProcess

	// inserting tcp message struct
	tcpMessage = common.TCPMessage{}

	tcpMessage.Kind = clientcommon.CheckJob
	tcpMessage.Version = clientcommon.Version
	tcpMessage.Hostname = hostName
	tcpMessage.ServerID = inputData.ServerID

	resultData.Result = 0
	resultData.HostJobList = inputData.JobIdList

	tcpMessage.Data = resultData
	data.TCPMessage = &tcpMessage

	// checking agent version (JAZ1 agent or JAZ2 agent)
	agentVersion, _, err = clientcommon.CheckJazVersion(ip, port, hostName, inputData.ServerID)
	if err != nil {
		return common.JA_JOBRESULT_SUCCEED, err
	}

	//connect tcp and send data
	conn, err = clientcommon.TcpConnect(ip, port, clientcommon.Timeout)
	if err != nil {
		return common.JA_JOBRESULT_SUCCEED, err
	}

	conn.SetSendTimeout(int64(clientcommon.Timeout))

	data.TCPMessage = &tcpMessage
	clientcommon.SendAndReceive(conn, data, agentVersion, inputData.Jaz1SupportFlag)
	return common.JA_JOBRESULT_SUCCEED, nil
}

func main() {
	var (
		exitCode int
		err      error
	)

	//catch runtime panic errors
	defer func() {
		if r := recover(); r != nil {
			//output stacktrace
			fmt.Fprintf(os.Stderr, "[checkJobClient] Runtime panic error occurs in client. error : %s", string(debug.Stack()))
			os.Exit(common.JA_JOBRESULT_FAIL)
		}
	}()

	clientcommon.ParseArgs()

	exitCode, err = checkJobClient()
	if err != nil {
		fmt.Fprintf(os.Stderr, "[checkJobClient] %v", err)
	}

	os.Exit(exitCode)
}
