/*
 * Copyright 2014-present Miyou tech inc. All Rights Reserved.
 */

package com.quantgroup.asset.distribution.exception;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static com.quantgroup.asset.distribution.exception.QGExceptionType.COMMON_SERVER_ERROR;
import static com.quantgroup.asset.distribution.exception.QGExceptionType.COMMON_THIRD_PARTY_TIMEOUT;

import java.net.SocketTimeoutException;
import java.util.Arrays;

public class QGException extends RuntimeException {

  private static final Logger LOGGER = LoggerFactory.getLogger(QGException.class);

  public QGExceptionType qgExceptionType;
  public boolean isToastFormat = false;
  public String detail;

  public QGException(String detail, QGExceptionType qgExceptionType, Object... args) {
    super(detail);
    try {
      if (StringUtils.isNoneBlank(qgExceptionType.frontEndToastTemplate)) {
        isToastFormat = true;
        initException(String.format(qgExceptionType.frontEndToastTemplate, args), qgExceptionType);
      } else {
        initException(qgExceptionType);
      }
    } catch (Exception e) {
      LOGGER.error("format front end toast err, " + qgExceptionType + ", args: " + Arrays.toString(args), e);
      initException(COMMON_SERVER_ERROR);
    }
  }

  public QGException(QGExceptionType qgExceptionType, Object... args) {
    super(qgExceptionType.text);
    try {
      if (StringUtils.isNoneBlank(qgExceptionType.frontEndToastTemplate)) {
        isToastFormat = true;
        initException(String.format(qgExceptionType.frontEndToastTemplate, args), qgExceptionType);
      } else {
        initException(qgExceptionType);
      }
    } catch (Exception e) {
      LOGGER.error("format front end toast err, " + qgExceptionType + ", args: " + Arrays.toString(args), e);
      initException(COMMON_SERVER_ERROR);
    }
  }

  public QGException(String detail, Throwable cause, QGExceptionType qgExceptionType) {
    super(detail, cause);
    this.initException(detail, qgExceptionType);
  }

  public QGException(String detail, QGExceptionType qgExceptionType) {
    super(detail);
    initException(detail, qgExceptionType);
  }

  public QGException(QGExceptionType qgExceptionType) {
    super(qgExceptionType.text);
    initException(qgExceptionType);
  }

  public QGException(Throwable cause, QGExceptionType qgExceptionType, Object... args) {
    super(qgExceptionType.text, cause);
    try {
      if (StringUtils.isNoneBlank(qgExceptionType.frontEndToastTemplate)) {
        isToastFormat = true;
        initException(String.format(qgExceptionType.frontEndToastTemplate, args), qgExceptionType);
      } else {
        initException(qgExceptionType);
      }
    } catch (Exception e) {
      LOGGER.error("format front end toast err, " + qgExceptionType + ", args: " + Arrays.toString(args), e);
      initException(COMMON_SERVER_ERROR);
    }
  }

  public static QGException wrap(Throwable e) {
    return wrap(e, COMMON_SERVER_ERROR);
  }

  public static QGException wrap(Throwable e, QGExceptionType exceptionType) {
    if (e instanceof QGException) {
      return (QGException) e;
    }
    if (e instanceof SocketTimeoutException)
      return new QGException(COMMON_THIRD_PARTY_TIMEOUT);
    return new QGException(e, exceptionType);
  }

  public static QGException wrap(Throwable e, QGExceptionType exceptionType, Object... args) {
    if (e instanceof QGException) {
      return (QGException) e;
    }
    if (e instanceof SocketTimeoutException)
      return new QGException(COMMON_THIRD_PARTY_TIMEOUT);
    return new QGException(e, exceptionType, args);
  }

  private void initException(QGExceptionType QGExceptionType) {
    this.initException(QGExceptionType.text, QGExceptionType);
  }

  private void initException(String detail, QGExceptionType QGExceptionType) {
    this.qgExceptionType = QGExceptionType;
    this.detail = detail;
  }
}