package com.red.circle.other.infra.database.mongo.service.sys.impl;

import com.red.circle.framework.mybatis.constant.PageConstant;
import com.red.circle.other.infra.database.mongo.entity.sys.ApiOperationLog;
import com.red.circle.other.infra.database.mongo.entity.sys.query.ApiOperationLogQuery;
import com.red.circle.other.infra.database.mongo.service.sys.ApiOperationLogService;
import com.red.circle.tool.core.text.StringUtils;
import java.util.List;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

/**
 * api请求日志 实现.
 *
 * @author pengliang on 2022/3/31
 */
@Service
@RequiredArgsConstructor
public class ApiOperationLogServiceImpl implements ApiOperationLogService {

  private static final Logger log = LoggerFactory.getLogger(ApiOperationLogServiceImpl.class);
  private final MongoTemplate mongoTemplate;

  @Override
  public void add(ApiOperationLog log) {
    try {
      mongoTemplate.save(log);
    } catch (DuplicateKeyException ex) {
      // ignore
    }
  }

  @Override
  public List<ApiOperationLog> list(ApiOperationLogQuery query) {
    log.warn("query{}", query);
    Criteria criteria = new Criteria();

    if (StringUtils.isNotBlank(query.getBusinessCode())) {
      criteria.and("businessCode").is(query.getBusinessCode());
    }
    if (StringUtils.isNotBlank(query.getBusinessContent())) {
      criteria.and("businessContent").is(query.getBusinessContent());
    }

    if (Objects.nonNull(query.getStartTime()) && Objects.nonNull(query.getEndTime())) {
      criteria.andOperator(
          Criteria.where("createTime").gte(query.getStartTime()),
          Criteria.where("createTime").lte(query.getEndTime())
      );
    } else if (Objects.nonNull(query.getStartTime())) {
      criteria.and("createTime").gte(query.getStartTime());
    } else if (Objects.nonNull(query.getEndTime())) {
      criteria.and("createTime").lte(query.getEndTime());
    }

    if (StringUtils.isNotBlank(query.getLastId())) {
      criteria.and("id").lt(query.getLastId());
    }
    if (StringUtils.isNotBlank(query.getCmdRegex())) {
      criteria.and("cmd").regex(query.getCmdRegex());
    }
    return mongoTemplate
        .find(Query.query(criteria).with(Sort.by(Sort.Order.desc("id")))
                .limit(PageConstant.limitSizeStrict(query.getSize())),
            ApiOperationLog.class);
  }
}
