/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.eventmesh.dashboard.core.dto;

import static org.apache.eventmesh.dashboard.core.enums.Status.SUCCESS;

import org.apache.eventmesh.dashboard.core.enums.Status;
import org.apache.eventmesh.dashboard.core.exception.BaseException;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * A RESTful response DTO.
 */

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Result<T> {

    private T data;

    private Integer pages;

    private StatusMessage message;

    public Result(StatusMessage statusMessage) {
        this.message = statusMessage;
    }

    public Result(T data, Integer pages) {
        this.data = data;
        this.pages = pages;
    }

    /**
     * The request is valid and the result is wrapped in {@link Result}.
     */
    public static <T> Result<T> success() {
        return new Result<>(new StatusMessage(SUCCESS));
    }

    public static <T> Result<T> success(Result<T> result) {
        result.setMessage(new StatusMessage(SUCCESS));
        return result;
    }

    public static <T> Result<T> success(T data) {
        return new Result<>(data, null, new StatusMessage(SUCCESS));
    }

    /**
     * The request is valid and the result is returned in {@link ResponseEntity}.
     * Logic issues should use 422 Unprocessable Entity instead of 200 OK.
     */
    public static <T> ResponseEntity<Result<T>> ok() {
        return ResponseEntity.ok(new Result<>(new StatusMessage(SUCCESS)));
    }

    public static <T> ResponseEntity<Result<T>> ok(Result<T> result) {
        result.setMessage(new StatusMessage(SUCCESS));
        return ResponseEntity.ok(result);
    }

    /**
     * The request is invalid.
     */
    public static <T> ResponseEntity<Result<T>> badRequest(String message) {
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new Result<>(new StatusMessage(message)));
    }

    /**
     * The request is valid but cannot be processed due to business logic issues.
     */
    public static <T> ResponseEntity<Result<T>> unprocessable(String message) {
        return ResponseEntity.status(HttpStatus.UNPROCESSABLE_ENTITY).body(new Result<>(new StatusMessage(message)));
    }

    /**
     * Uncaught exception happened in EventMeshAdmin application.
     */
    public static <T> ResponseEntity<Result<T>> internalError(String message) {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(new Result<>(new StatusMessage(message)));
    }

    /**
     * Upstream service unavailable such as Meta.
     */
    public static <T> ResponseEntity<Result<T>> badGateway(String message) {
        return ResponseEntity.status(HttpStatus.BAD_GATEWAY).body(new Result<>(new StatusMessage(message)));
    }

    @Data
    public static class StatusMessage {

        private String status;

        private String category;

        private String desc;

        public StatusMessage(BaseException e) {
            this.status = e.getStatus().name();
            this.category = e.getStatus().getCategory().name();
            this.desc = e.getMessage();
        }

        /**
         * Only recommended for returning successful results,
         * the stack trace cannot be displayed when returning unsuccessful results.
         */
        public StatusMessage(Status status) {
            this.status = status.name();
            this.category = status.getCategory().name();
            this.desc = status.getDesc(); // no stack trace
        }

        public StatusMessage(String desc) {
            this.desc = desc;
        }
    }
}
