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

import (
	"errors"
	"fmt"
	"net/http"
)

type RequestContext struct {
	FunctionArn string `json:"functionArn"`
}

type ResponseContext struct {
	StatusCode      int    `json:"statusCode"`
	ExecutedVersion string `json:"executedVersion"`
}

type RequestPayload struct {
	TaskID string `json:"task_id"`
}

type Event struct {
	RequestContext  RequestContext         `json:"requestContext"`
	RequestPayload  RequestPayload         `json:"requestPayload"`
	ResponseContext ResponseContext        `json:"responseContext"`
	ResponsePayload map[string]interface{} `json:"responsePayload"`
}

func (e *Event) Validate() error {
	if e.RequestPayload.TaskID == "" {
		return errors.New("event.requestPayload.task_id is empty")
	}
	if e.RequestContext.FunctionArn == "" {
		return errors.New("event.requestContext.functionArn is empty")
	}
	return nil
}

func (e *Event) NeedResume() bool {
	code, _ := e.ResponsePayload["code"].(float64)
	_, hasStrContext := e.ResponsePayload["context"].(string)
	return code == http.StatusPartialContent && hasStrContext
}

func (e *Event) Failed() bool {
	code, _ := e.ResponsePayload["code"].(float64)
	return code >= 400 ||
		e.ResponseContext.StatusCode != 200 ||
		e.ResponsePayload["errorType"] != nil ||
		e.ResponsePayload["errorMessage"] != nil
}

func (e *Event) GetInvokePayload() []byte {
	return []byte(fmt.Sprintf(`{"resume_context": "%s", "task_id": "%s"}`, e.ResponsePayload["context"], e.RequestPayload.TaskID))
}

func (e *Event) GetTaskID() string {
	return e.RequestPayload.TaskID
}

func (e *Event) GetFunctionArn() string {
	return e.RequestContext.FunctionArn
}
