/*
** 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"

	"jobarranger2/src/libs/golibs/common"
	"jobarranger2/src/libs/golibs/database"
	"jobarranger2/src/libs/golibs/event"
	"jobarranger2/src/libs/golibs/utils"
)

func processIconStatusSync(jobnetPayload common.EventData, dbconn database.DBConnection) error {
	var eventName common.EventName
	var actionIconData common.ActionIconData
	funcname := "processIconRerunStatusSync"
	JobnetRunLogger.JaLog("JAJOBNETRUN400001", funcname)
	queries := []common.ParameterizedQuery{}

	jobnetRunData, err := getJobnetRunData(jobnetPayload.NextProcess.Data)
	if err != nil {
		return fmt.Errorf("%s", err.Error())
	}
	currentFilePath := jobnetPayload.Transfer.Files[0].Source

	switch jobnetPayload.Event.Name {
	case common.EventIconRerunStatusSync:
		eventName = common.EventIconRerun
		actionIconData = common.ActionIconData{
			InnerJobnetID: jobnetRunData.InnerJobnetId,
			JobnetID:      jobnetRunData.JobnetID,
			InnerJobID:    jobnetRunData.InnerJobId,
			MethodFlag:    common.MethodRerun,
		}
	case common.EventIconRunErrSkip:
		eventName = common.EventFlowIconSkip
		actionIconData = common.ActionIconData{
			InnerJobnetID: jobnetRunData.InnerJobnetId,
			JobnetID:      jobnetRunData.JobnetID,
			InnerJobID:    jobnetRunData.InnerJobId,
			MethodFlag:    common.MethodSkip,
		}
	case common.EventFlowJobnetIconStatusChange:
		currentFilePath = jobnetPayload.Transfer.Files[0].Destination
		actionIconData = jobnetRunData.ActionIconData
		if jobnetRunData.ActionIconData.MethodFlag == common.MethodRerun {
			eventName = common.EventIconRerun
		} else {
			eventName = common.EventFlowIconSkip
		}
	default:

	}

	runErrJobidList, err := utils.GetCountByJobIdAndStatus(dbconn, jobnetRunData.InnerJobnetId, jobnetRunData.InnerJobId, common.StatusRunErr)
	if err != nil {
		return fmt.Errorf("%s", err.Error())
	}

	events := []common.EventData{}
	if runErrJobidList == 0 {
		isSubJobnet, _, err := IsSubJobnet(dbconn, jobnetRunData.InnerJobnetId)
		if err != nil {
			return fmt.Errorf("%s", err.Error())
		}
		JobnetRunLogger.JaLog("JAJOBNETRUN000009")

		if !isSubJobnet {
			queries = jaSetJobStatusSummary(jobnetRunData.InnerJobnetId, JA_SUMMARY_JOB_STATUS_NORMAL, queries...)
			queries = jaSetStatusJobnet(jobnetRunData.InnerJobnetId, JA_JOBNET_STATUS_RUN, -1, -1, queries...)

			if eventName == common.EventIconRerun {
				nextEvent := prepareNextEventData(
					common.EventIconRerunJobnetStatusChange,
					common.DBSyncerManagerProcess,
					common.FlowProcessData{
						InnerJobnetId: actionIconData.InnerJobnetID,
						InnerJobId:    actionIconData.InnerJobID,
						JobnetId:      actionIconData.JobnetID,
					},
					queries,
				)
				events = append(events, nextEvent)
			} else {
				nextEvent := prepareNextEventData(
					common.EventJobnetStatusChange,
					common.DBSyncerManagerProcess,
					map[string]any{},
					queries,
				)
				events = append(events, nextEvent)

				nextEvent = prepareNextEventData(
					eventName,
					common.FlowManagerProcess,
					common.FlowProcessData{
						InnerJobnetId: actionIconData.InnerJobnetID,
						InnerJobId:    actionIconData.InnerJobID,
						JobnetId:      actionIconData.JobnetID,
					},
					[]common.ParameterizedQuery{},
				)
				events = append(events, nextEvent)
			}

		} else {
			queries = jaSetStatusJobnet(jobnetRunData.InnerJobnetId, JA_JOBNET_STATUS_RUN, -1, -1, queries...)

			nextEvent := prepareNextEventData(
				common.EventSubJobnetStatusChange,
				common.FlowManagerProcess,
				common.FlowProcessData{
					InnerJobnetId: jobnetRunData.InnerJobnetId,
					JobnetId:      jobnetRunData.JobnetID,
					Status:        common.StatusRun,
					Data:          actionIconData,
				},
				queries,
			)
			events = append(events, nextEvent)
		}

	} else {
		nextEvent := prepareNextEventData(
			eventName,
			common.FlowManagerProcess,
			common.FlowProcessData{
				InnerJobnetId: actionIconData.InnerJobnetID,
				InnerJobId:    actionIconData.InnerJobID,
				JobnetId:      actionIconData.JobnetID,
			},
			[]common.ParameterizedQuery{},
		)
		events = append(events, nextEvent)
	}

	for _, nextEvent := range events {
		JobnetRunLogger.JaLog("JAJOBNETRUN400009", nextEvent)
		err := event.CreateNextEvent(nextEvent, jobnetRunData.InnerJobnetId, jobnetRunData.JobnetID, jobnetRunData.InnerJobId)
		if err != nil {
			return fmt.Errorf("%s", err.Error())
		}
	}

	//move incoming file to end folder.
	err = utils.MoveToSubFolder(currentFilePath, END)
	if err != nil {
		return fmt.Errorf("moveFile from current %s to %s failed : %s", currentFilePath, END, err.Error())
	}

	JobnetRunLogger.JaLog("JAJOBNETRUN400002", funcname)
	return nil
}
