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

	"jobarranger2/src/libs/golibs/common"
)

func jaTimestamp2Str() string {
	return fmt.Sprintf("%d", time.Now().Unix())
}
func jaSetStatusJobnetSummary(innerJobnetId uint64, status common.StatusType, start, end int, queries ...common.ParameterizedQuery) []common.ParameterizedQuery {
	var timestamp, strStart, strEnd string
	if runJobnetTable.RunType == common.JA_JOBNET_RUN_TYPE_TEST {
		timestamp = fmt.Sprintf("%d", time.Now().Unix()-int64(runJobnetTable.CreatedDate)+int64(runJobnetTable.TestRunTime))
	} else {
		timestamp = jaTimestamp2Str()
	}
	strStart = buildTimeClause("start_time", start, timestamp)
	strEnd = buildTimeClause("end_time", end, timestamp)

	var updateSql string
	if status == common.StatusEnd || status == common.StatusEndErr {
		deleteSql := fmt.Sprintf("DELETE from %s where inner_jobnet_main_id= ? ", common.Ja2SessionTable)
		queries = append(queries, common.GetPQ(deleteSql, innerJobnetId))

		updateSql = fmt.Sprintf(
			"update %s set status = ? %s%s ,running_job_id = '', running_job_name = '' where inner_jobnet_id = ?",
			common.Ja2RunJobnetSummaryTable, strStart, strEnd,
		)
		queries = append(queries, common.GetPQ(updateSql, status, innerJobnetId))
	} else {
		updateSql = fmt.Sprintf(
			"update %s set status = ? %s%s where inner_jobnet_id = ?",
			common.Ja2RunJobnetSummaryTable, strStart, strEnd,
		)
		queries = append(queries, common.GetPQ(updateSql, status, innerJobnetId))
	}
	return queries
}

func jaSetStatusJobnet(innerJobnetId uint64, status common.StatusType, start, end int, queries ...common.ParameterizedQuery) []common.ParameterizedQuery {
	var timestamp, strStart, strEnd string
	if runJobnetTable.RunType == common.JA_JOBNET_RUN_TYPE_TEST {
		timestamp = fmt.Sprintf("%d", time.Now().Unix()-int64(runJobnetTable.CreatedDate)+int64(runJobnetTable.TestRunTime))
	} else {
		timestamp = jaTimestamp2Str()
	}
	strStart = buildTimeClause("start_time", start, timestamp)
	strEnd = buildTimeClause("end_time", end, timestamp)

	updateSQL := fmt.Sprintf("update %s set status = ? %s%s where inner_jobnet_id = ?", common.Ja2RunJobnetTable, strStart, strEnd)
	paramQuery := common.GetPQ(updateSQL, status, innerJobnetId)
	return append(queries, paramQuery)
}

func buildTimeClause(field string, flag int, timestamp string) string {
	switch flag {
	case 0:
		return fmt.Sprintf(", %s = 0", field)
	case 1:
		return fmt.Sprintf(", %s = %s", field, timestamp)
	default:
		return ""
	}
}

func jaSetStatusJobnetWait(innerJobnetId uint64, queries ...common.ParameterizedQuery) []common.ParameterizedQuery {
	query := fmt.Sprintf(
		"update %s set load_status = ? where inner_jobnet_id = ?",
		common.Ja2RunJobnetSummaryTable,
	)
	return append(queries, common.GetPQ(query, common.JA_SUMMARY_LOAD_STATUS_DELAY, innerJobnetId))
}

func jaSetStatusJobnetSkip(innerJobnetId uint64, queries ...common.ParameterizedQuery) []common.ParameterizedQuery {
	now := time.Now().Unix()
	updateSQL := []common.ParameterizedQuery{}
	summaryQuery := fmt.Sprintf(
		"update %s set status = ?, load_status = ?, start_time = ?, end_time = ? where inner_jobnet_id = ?",
		common.Ja2RunJobnetSummaryTable,
	)
	updateSQL = append(updateSQL, common.GetPQ(summaryQuery, JA_JOBNET_STATUS_END, common.JA_SUMMARY_LOAD_STATUS_SKIP, now, now, innerJobnetId))

	jobnetQuery := fmt.Sprintf(
		"update %s set status = ?, start_time = ?, end_time = ? where inner_jobnet_id = ?",
		common.Ja2RunJobnetTable,
	)
	updateSQL = append(updateSQL, common.GetPQ(jobnetQuery, JA_JOBNET_STATUS_END, now, now, innerJobnetId))

	return append(queries, updateSQL...)
}

func jaSetStatusJobnetTimeout(innerJobnetId uint64, jobnet_timeout_run_type int, queries ...common.ParameterizedQuery) []common.ParameterizedQuery {
	switch jobnet_timeout_run_type {
	case 0:
		//Timeout Warning
		summaryQuery := fmt.Sprintf(
			"update %s set job_status = ?, jobnet_abort_flag = ?, jobnet_timeout_flag =1 where inner_jobnet_id = ?",
			common.Ja2RunJobnetSummaryTable,
		)
		queries = append(queries, common.GetPQ(summaryQuery, JA_SUMMARY_JOB_STATUS_TIMEOUT, jobnet_timeout_run_type, innerJobnetId))
	case 1:
		summaryQuery := fmt.Sprintf(
			"update %s set status = ?, job_status = ?, jobnet_abort_flag = ?, jobnet_timeout_flag =1 where inner_jobnet_id = ?",
			common.Ja2RunJobnetSummaryTable,
		)
		queries = append(queries, common.GetPQ(summaryQuery, JA_JOBNET_STATUS_RUN, JA_SUMMARY_JOB_STATUS_ERROR, jobnet_timeout_run_type, innerJobnetId))

	}
	return queries

}

func jaSetStatusIconTimeoutWarning(innerJobnetId uint64, queries ...common.ParameterizedQuery) []common.ParameterizedQuery {
	timeoutFlagQuery := fmt.Sprintf(
		"UPDATE %s set timeout_flag=1 where inner_jobnet_id = ?",
		common.Ja2RunJobnetTable,
	)
	queries = append(queries, common.GetPQ(timeoutFlagQuery, innerJobnetId))

	timeoutWarningQuery := fmt.Sprintf(
		"UPDATE %s set job_status = ? where inner_jobnet_id = ?",
		common.Ja2RunJobnetSummaryTable,
	)
	queries = append(queries, common.GetPQ(timeoutWarningQuery, JA_SUMMARY_JOB_STATUS_TIMEOUT, innerJobnetId))

	return queries
}

func jaStatusJobnetDelayStart(innerJobnetId uint64, queries ...common.ParameterizedQuery) []common.ParameterizedQuery {
	now := time.Now().Unix()
	updateSql := fmt.Sprintf(
		"update %s set update_date = ?, status = ?, job_status = ?, load_status = ? where inner_jobnet_id = ?",
		common.Ja2RunJobnetSummaryTable,
	)
	queries = append(queries, common.GetPQ(updateSql, now, JA_JOBNET_STATUS_RUN, JA_SUMMARY_JOB_STATUS_ERROR, common.JA_SUMMARY_LOAD_STATUS_DELAY, innerJobnetId))

	return queries
}

func jaStatusScheduleJobnetDelete(innerJobnetMainId uint64, queries ...common.ParameterizedQuery) []common.ParameterizedQuery {
	futureTime := time.Now().Add(5 * time.Minute).Unix()

	deleteSql := fmt.Sprintf(
		"delete from %s where inner_jobnet_main_id= ? and scheduled_time > ?",
		common.Ja2RunJobnetTable,
	)
	return append(queries, common.GetPQ(deleteSql, innerJobnetMainId, futureTime))
}

func jaStatusJobnetHoldSummary(innerJobnetId uint64, queries ...common.ParameterizedQuery) []common.ParameterizedQuery {
	holdSql := fmt.Sprintf(
		"update %s set start_pending_flag=? where inner_jobnet_id=? and status=?",
		common.Ja2RunJobnetSummaryTable,
	)
	return append(queries, common.GetPQ(holdSql, JA_SUMMARY_START_PENDING_ON, innerJobnetId, JA_JOBNET_STATUS_BEGIN))
}

func jaStatusJobnetReleaseSummary(innerJobnetId uint64, queries ...common.ParameterizedQuery) []common.ParameterizedQuery {
	releaseSql := fmt.Sprintf(
		"update %s set start_pending_flag=? where inner_jobnet_id=? and start_pending_flag=?",
		common.Ja2RunJobnetSummaryTable,
	)
	return append(queries, common.GetPQ(releaseSql, JA_SUMMARY_START_PENDING_OFF, innerJobnetId, JA_SUMMARY_START_PENDING_ON))
}

func jaStartTheJobnet(innerJobnetId uint64, queries ...common.ParameterizedQuery) []common.ParameterizedQuery {
	updateSql := fmt.Sprintf(
		"update %s set load_status = ? where inner_jobnet_id = ?",
		common.Ja2RunJobnetSummaryTable,
	)
	queries = append(queries, common.GetPQ(updateSql, JA_SUMMARY_JOB_STATUS_NORMAL, innerJobnetId))
	return queries
}

func jaSetEndingFlagSummary(innerJobnetId uint64, endingflag int, queries ...common.ParameterizedQuery) []common.ParameterizedQuery {
	query := fmt.Sprintf("update %s set ending_flag = ? where inner_jobnet_id = ?",
		common.Ja2RunJobnetSummaryTable,
	)

	return append(queries, common.GetPQ(query, endingflag, innerJobnetId))
}

func jaSetEndingFlagJobnet(innerJobnetId uint64, endingflag int, queries ...common.ParameterizedQuery) []common.ParameterizedQuery {
	query := fmt.Sprintf("update %s set ending_flag =? where inner_jobnet_id = ?",
		common.Ja2RunJobnetTable,
	)

	return append(queries, common.GetPQ(query, endingflag, innerJobnetId))
}

func jaSetAbortFlagSummary(innerJobnetId uint64, queries ...common.ParameterizedQuery) []common.ParameterizedQuery {
	query := fmt.Sprintf("update %s set jobnet_abort_flag = ? where inner_jobnet_id = ? AND status = ?",
		common.Ja2RunJobnetSummaryTable,
	)

	return append(queries, common.GetPQ(query, JA_JOBNET_ABORT_FLAG_ON, innerJobnetId, JA_JOBNET_STATUS_RUN))
}

func jaSetJobStatusSummary(innerJobnetId uint64, jobStatus JobStatusSummary, queries ...common.ParameterizedQuery) []common.ParameterizedQuery {
	query := fmt.Sprintf("update %s set job_status = ? where inner_jobnet_id = ?",
		common.Ja2RunJobnetSummaryTable,
	)

	return append(queries, common.GetPQ(query, jobStatus, innerJobnetId))
}

func jaSetAbortFlagTimeout(innerJobnetId uint64, queries ...common.ParameterizedQuery) []common.ParameterizedQuery {
	query := fmt.Sprintf("update %s set abort_flag= true where inner_jobnet_id = ?",
		common.Ja2RunTimeOutTable)

	return append(queries, common.GetPQ(query, innerJobnetId))
}

func jaSetEndFlagTimeout(innerJobnetId uint64, queries ...common.ParameterizedQuery) []common.ParameterizedQuery {
	query := fmt.Sprintf("update %s set end_flag= true where inner_jobnet_id = ?",
		common.Ja2RunTimeOutTable)
	return append(queries, common.GetPQ(query, innerJobnetId))
}

func jaSetRunningJobIdSummary(innerJobnetId uint64, errorJobId string, queries ...common.ParameterizedQuery) []common.ParameterizedQuery {
	query := fmt.Sprintf("UPDATE %s set running_job_id = ? where inner_jobnet_id = ?",
		common.Ja2RunJobnetSummaryTable)
	return append(queries, common.GetPQ(query, errorJobId, innerJobnetId))
}

func jaSetScheduledTime(innerJobnetId uint64, scheduleTime uint64, queries ...common.ParameterizedQuery) []common.ParameterizedQuery {
	runQuery := fmt.Sprintf("UPDATE %s set scheduled_time = ? where inner_jobnet_id = ? and status = ?",
		common.Ja2RunJobnetTable,
	)
	queries = append(queries, common.GetPQ(runQuery, scheduleTime,
		innerJobnetId,
		JA_JOBNET_STATUS_BEGIN))

	summaryQuery := fmt.Sprintf("UPDATE %s set scheduled_time = ? where inner_jobnet_id = ? and status = ?",
		common.Ja2RunJobnetSummaryTable,
	)
	queries = append(queries, common.GetPQ(summaryQuery, scheduleTime,
		innerJobnetId,
		JA_JOBNET_STATUS_BEGIN))

	return queries
}
