package com.mingzuozhibi.modules.spider;

import com.google.gson.reflect.TypeToken;
import com.mingzuozhibi.commons.amqp.logger.LoggerBind;
import com.mingzuozhibi.commons.base.BaseSupport;
import com.mingzuozhibi.commons.domain.Result;
import com.mingzuozhibi.commons.domain.SearchTask;
import com.mingzuozhibi.commons.utils.ThreadUtils;
import com.mingzuozhibi.modules.disc.Disc;
import com.mingzuozhibi.modules.disc.Disc.DiscType;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.time.Instant;
import java.time.LocalDate;
import java.util.*;

import static com.mingzuozhibi.commons.amqp.AmqpEnums.*;
import static com.mingzuozhibi.commons.utils.FormatUtils.fmtDate;
import static com.mingzuozhibi.support.ModifyUtils.getName;

@Component
@LoggerBind(Name.SERVER_USER)
public class ContentService extends BaseSupport {

    private final Map<String, SearchTask<Content>> waitMap = Collections.synchronizedMap(new HashMap<>());

    public Result<Content> doGet(String asin) {
        SearchTask<Content> task = contentSearch(asin);
        return Result.ofTask(task).ifSuccess((data, result) -> {
            if (data.isOffTheShelf()) {
                result.withError("可能该碟片已下架");
            }
        });
    }

    public Disc createWith(Content content) {
        String asin = content.getAsin();
        String title = content.getTitle();
        DiscType discType = DiscType.valueOf(content.getType());
        LocalDate releaseDate = Optional.ofNullable(content.getDate())
            .map(date -> LocalDate.parse(date, fmtDate))
            .orElse(null);
        return new Disc(asin, title, discType, releaseDate);
    }

    private SearchTask<Content> contentSearch(String asin) {
        SearchTask<Content> task = new SearchTask<>(asin);
        amqpSender.send(CONTENT_SEARCH, gson.toJson(task));
        String uuid = task.getUuid();
        waitMap.put(uuid, task);

        long time = Instant.now().toEpochMilli();
        ThreadUtils.waitSecond(task, 30);
        long cost = Instant.now().toEpochMilli() - time;

        SearchTask<Content> remove = waitMap.remove(uuid);
        if (remove == task) {
            bind.warning("[%s][查询碟片超时][asin=%s][cost=%d ms]", getName(), asin, cost);
        } else if (!remove.isSuccess()) {
            String format = "[%s][查询碟片失败][asin=%s][cost=%d ms][error=%s]";
            bind.warning(format, getName(), asin, cost, remove.getMessage());
        } else {
            bind.success("[%s][查询碟片成功][asin=%s][cost=%d ms]", getName(), asin, cost);
        }
        return remove;
    }

    @RabbitListener(queues = CONTENT_RETURN)
    public void contentReturn(String json) {
        TypeToken<?> token = TypeToken.getParameterized(SearchTask.class, Content.class);
        SearchTask<Content> task = gson.fromJson(json, token.getType());
        SearchTask<Content> lock = waitMap.remove(task.getUuid());
        if (lock != null) {
            waitMap.put(task.getUuid(), task);
            ThreadUtils.notifyAll(lock);
        }
    }

}

@@ -2051,10 +2051,10 @@
 sk, 
-30
+15
 );%0A 
@@ -2184,131 +2184,8 @@
  if 
-(remove == task) %7B%0A            bind.warning(%22%5B%25s%5D%5B%E6%9F%A5%E8%AF%A2%E7%A2%9F%E7%89%87%E8%B6%85%E6%97%B6%5D%5Basin=%25s%5D%5Bcost=%25d ms%5D%22, getName(), asin, cost);%0A        %7D else if 
 (!re
@@ -2220,24 +2220,21 @@
     
-String format = 
+bind.warning(
 %22%5B%25s
@@ -2274,17 +2274,17 @@
 ror=%25s%5D%22
-;
+,
 %0A       
@@ -2292,28 +2292,11 @@
     
-bind.warning(format,
+   
  get
@@ -2341,111 +2341,8 @@
 ));%0A
-        %7D else %7B%0A            bind.success(%22%5B%25s%5D%5B%E6%9F%A5%E8%AF%A2%E7%A2%9F%E7%89%87%E6%88%90%E5%8A%9F%5D%5Basin=%25s%5D%5Bcost=%25d ms%5D%22, getName(), asin, cost);%0A
     

Update content search