package com.pingcap.kb.integration.service;

import com.pingcap.kb.integration.dao.KbPostStatusDao;
import com.pingcap.kb.integration.kb.KbClient;
import com.pingcap.kb.integration.kb.Post;
import com.pingcap.kb.integration.kb.Post.Meta;
import com.pingcap.kb.integration.kb.Solution;
import com.pingcap.kb.integration.kb.Solution.Locale;
import com.pingcap.kb.integration.kb.SolutionIterator;
import com.pingcap.kb.integration.template.HandlebarsService;
import java.io.IOException;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class KbService {

  private final KbClient kbClient;
  private final KbPostStatusDao kbPostStatusDao;
  private final HandlebarsService handlebarsService;

  public KbService(KbClient kbClient, KbPostStatusDao kbPostStatusDao, HandlebarsService handlebarsService) {
    this.kbClient = kbClient;
    this.kbPostStatusDao = kbPostStatusDao;
    this.handlebarsService = handlebarsService;
  }

  public Iterable<Solution> findSolutions(SolutionIterator.Fetcher fetcher) {
    return new SolutionIterator(kbClient, fetcher);
  }

  public Stream<Solution> findTrackingSolutions() {
    return kbPostStatusDao.findAll("solutions", true)
        .flatMap(kbPostStatus -> kbClient.getSolution(kbPostStatus.getKbId()).stream());
  }

  public String renderTemplate(String template, Solution solution, RenderContext ctx) throws IOException {
    for (Locale locale : solution.getLocales()) {
      if (locale.getLocale().equals("zh")) {
        ctx.locales.zh = locale;
        ctx.locales.hasZh = true;
      } else if (locale.getLocale().equals("en")) {
        ctx.locales.en = locale;
        ctx.locales.hasEn = true;
      }
    }
    if (ctx.locales.en != null) {
      ctx.title = ctx.locales.en.getTitle();
    } else {
      ctx.title = ctx.locales.zh.getTitle();
    }
    ctx.product = solution.getProduct().getName();
    ctx.components = solution.getComponents().stream().map(Meta::getName).collect(Collectors.joining(" "));
    ctx.categories = solution.getCategories().stream().map(Meta::getName).collect(Collectors.joining(" "));
    ctx.affectedVersions = solution.getAffectedVersions().stream().map(Meta::getName).collect(Collectors.joining(" "));
    ctx.tags = solution.getTags().stream().map(Meta::getName).collect(Collectors.joining(" "));
    ctx.backTrackLink = solution.getBackTrackLink();
    ctx.remarkText = solution.getRemark();
    ctx.kbLink = kbClient.buildLink("solutions", solution.getId());
    return handlebarsService.render(template, ctx);
  }

  @Data
  public static class RenderContext {
    public String title;
    public String product;
    public String components;
    public String categories;
    public String affectedVersions;
    public String tags;
    public String backTrackLink;
    public String remarkText;
    public String kbLink;
    public Locales locales = new Locales();

    @Data
    public static class Locales {
      public boolean hasEn = false;
      public boolean hasZh = false;
      public Solution.Locale en;
      public Solution.Locale zh;
    }
  }

}
