// 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 dynamo

import (
	"encoding/json"
	"time"

	"github.com/pingcap-inc/compute-engine/pkg/database/model"
)

type Task struct {
	TaskID    string         `json:"id"`
	TaskName  string         `json:"task_name"`
	Status    int            `json:"status"`
	Hook      string         `json:"hook"`
	CreatedAt int64          `json:"created_at"`
	UpdatedAt int64          `json:"updated_at"`
	Tags      []KeyValuePair `json:"-"`
	Args      []KeyValuePair `json:"-"`
	Data      []KeyValuePair `json:"-"`
}

type KeyValuePair struct {
	TaskID string `json:"task_id"`
	Key    string `json:"key"`
	Value  string `json:"value"`
}

func (task *Task) Instance() (*model.TaskInstance, error) {
	tags := map[string]interface{}{}
	for _, t := range task.Tags {
		var v interface{}
		if err := json.Unmarshal([]byte(t.Value), &v); err != nil {
			return nil, err
		}
		tags[t.Key] = v
	}

	args := map[string]interface{}{}
	for _, t := range task.Args {
		var v interface{}
		if err := json.Unmarshal([]byte(t.Value), &v); err != nil {
			return nil, err
		}
		args[t.Key] = v
	}

	data := map[string]interface{}{}
	for _, d := range task.Data {
		var v interface{}
		if err := json.Unmarshal([]byte(d.Value), &v); err != nil {
			return nil, err
		}
		data[d.Key] = v
	}

	return &model.TaskInstance{
		ID:        task.TaskID,
		Task:      task.TaskName,
		Status:    model.TaskStatus(task.Status),
		Hook:      task.Hook,
		Tags:      tags,
		Args:      args,
		Data:      data,
		CreatedAt: model.JSONTime(time.Unix(task.CreatedAt, 0)),
		UpdatedAt: model.JSONTime(time.Unix(task.UpdatedAt, 0)),
	}, nil
}
