/*
 * Copyright (c) 2020 pig4cloud Authors. All Rights Reserved.
 *
 * 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,
 * 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 com.chushang.common.core.web;

import lombok.*;
import lombok.experimental.Accessors;

import java.io.Serial;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

/**
 * 响应信息主体
 *
 * @author lengleng
 */
@Setter
@Getter
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class Result<T> implements Serializable {
	public static final int SUCCESS_CODE = 200;
	public static final String SUCCESS_MSG = "success";
	public static final String FAIL_MSG = "fail";
	public static final int FAIL_CODE = 500;


	@Serial
	private static final long serialVersionUID = 1L;

	private int code;

	private String msg;

	private T data;

	public static Result<Map<String, Object>> putAll(Map<String, Object> params) {
		return Result.responseData()
				.addParams(params)
				.build();
	}

	public static Result<Map<String, Object>> put(String key, Object data) {
		return Result.responseData()
				.addParam(key, data)
				.build();
	}

	public static <T> Result<T> ok() {
		return restResult(null, SUCCESS_CODE, SUCCESS_MSG);
	}

	public static <T> Result<T> ok(T data) {
		return restResult(data, SUCCESS_CODE, SUCCESS_MSG);
	}

	public static <T> Result<T> ok(T data, String msg) {
		return restResult(data, SUCCESS_CODE, SUCCESS_MSG);
	}

	public static <T> Result<T> failed() {
		return restResult(null, FAIL_CODE, FAIL_MSG);
	}

	public static <T> Result<T> failed(String msg) {
		return restResult(null, FAIL_CODE, msg);
	}

	public static <T> Result<T> failedFeign(){
		return restResult(null, FAIL_CODE, "请稍后再试");
	}

	public static <T> Result<T> failed(T data) {
		return restResult(data, FAIL_CODE, FAIL_MSG);
	}

	public static <T> Result<T> failed(T data, String msg) {
		return restResult(data, FAIL_CODE, msg);
	}

	public static <T> Result<T> failed(int code, String msg) {
		return restResult(null, code, msg);
	}

	public static <T> Result<T> restResult(T data, int code, String msg) {
		Result<T> apiResult = new Result<>();
		apiResult.setCode(code);
		apiResult.setData(data);
		apiResult.setMsg(msg);
		return apiResult;
	}

	public static ResultMap responseData(){
		return new ResultMap();
	}

	public static class ResultMap {
		private final Map<String, Object> resultMap = new HashMap<>();

		public ResultMap addParam(String key, Object value){
			this.resultMap.put(key, value);
			return this;
		}

		public ResultMap addParams(Map<String, Object> params) {
			this.resultMap.putAll(params);
			return this;
		}

		public Result<Map<String, Object>> build(){
			return Result.ok(this.resultMap);
		}

	}

	public boolean isSuccess() {
		return SUCCESS_CODE == this.code;
	}

}
