// Copyright 2022 PingCAP, Inc.
//
// Licensed 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,
// See the License for the specific language governing permissions and
// limitations under the License.

package model

import (
	"fmt"
	"time"
)

type TaskType int

const (
	Lambda TaskType = 1 << iota
)

type TaskStatus int

const (
	Pending TaskStatus = 1 << iota
	Running
	Success
	Failed
)

// String implements Stringer
func (s TaskStatus) String() string {
	switch s {
	case Pending:
		return "pending"
	case Running:
		return "running"
	case Success:
		return "success"
	case Failed:
		return "failed"
	}
	return ""
}

func (s TaskStatus) MarshalJSON() ([]byte, error) {
	status := fmt.Sprintf("\"%s\"", s.String())
	return []byte(status), nil
}

type JSONTime time.Time

func (t JSONTime) MarshalJSON() ([]byte, error) {
	stamp := fmt.Sprintf("%d", time.Time(t).Unix())
	return []byte(stamp), nil
}

type TaskInstance struct {
	ID        string                 `json:"id"`
	Task      string                 `json:"name"`
	Hook      string                 `json:"hook"`
	Status    TaskStatus             `json:"status"`
	Tags      map[string]interface{} `json:"tags"`
	Args      map[string]interface{} `json:"args"`
	Data      map[string]interface{} `json:"data"`
	CreatedAt JSONTime               `json:"created_at"`
	UpdatedAt JSONTime               `json:"updated_at"`
}

type TaskInterface interface {
	Instance() (*TaskInstance, error)
}

type TaskModel interface {
	PutInstance(instance *TaskInstance) error
	GetInstanceList(ids []string) ([]TaskInstance, error)
	SearchInstance(
		taskName string,
		status int,
		begin *time.Time,
		end *time.Time,
		tags map[string]interface{},
		args map[string]interface{},
		data map[string]interface{},
	) ([]string, error)
	Close() error
}
