package br.gov.servicos.editor.servicos;

import br.gov.servicos.editor.xml.ArquivoXml;
import com.github.slugify.Slugify;
import lombok.SneakyThrows;
import lombok.experimental.FieldDefaults;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;
import java.util.ArrayList;
import java.util.Optional;
import java.util.stream.Stream;

import static java.lang.String.format;
import static java.nio.charset.Charset.defaultCharset;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;
import static lombok.AccessLevel.PRIVATE;

@Slf4j
@Component
@FieldDefaults(level = PRIVATE, makeFinal = true)
class ImportadorServicoV1 {

    File repositorioCartasLocal;
    Slugify slugify;

    @Autowired
    public ImportadorServicoV1(File repositorioCartasLocal, Slugify slugify) {
        this.repositorioCartasLocal = repositorioCartasLocal;
        this.slugify = slugify;
    }

    @SneakyThrows
    public Optional<Servico> carregar(String id) {
        File arquivo = new File(format("%s/cartas-servico/v1/servicos/%s.xml", repositorioCartasLocal.getPath(), id));
        if (!arquivo.exists()) {
            log.info("Arquivo {} não encontrado", arquivo);
            return Optional.empty();
        }

        log.info("Arquivo {} encontrado", arquivo);
        return carregar(new ArquivoXml(Jsoup.parse(arquivo, defaultCharset().name()).select("servico").first()));
    }

    public Optional<Servico> carregar(ArquivoXml xml) {
        return Optional.of(new Servico()
                .withMetadados(new Metadados()
                        .withVersao("1"))
                .withNome(xml.texto("nome"))
                .withNomesPopulares(xml.texto("nomesPopulares"))
                .withPalavrasChave(xml.texto("palavrasChave"))
                .withSolicitantes(emptyList())
                .withSituacao("")
                .withLegislacoes(emptyList())
                .withDescricao(xml.html("descricao") + "\n\n" + informacoesUteis(xml))
                .withOrgao(xml.converte("orgaoResponsavel", this::orgao))
                .withEventosDaLinhaDaVida(xml.coleta("eventosDaLinhaDaVida > eventoDaLinhaDaVida > nome"))
                .withAreasDeInteresse(xml.coleta("areasDeInteresse > areaDeInteresse > nome"))
                .withSegmentosDaSociedade(xml.coleta("segmentosDaSociedade > segmentoDaSociedade > nome",
                        ArquivoXml::texto,
                        x -> "Serviços aos Cidadãos".equals(x) ? "Cidadãos" : x,
                        x -> "Serviços às Empresas".equals(x) ? "Empresas" : x
                ))
                .withEtapas(singletonList(new Etapa()
                        .withTitulo("")
                        .withDescricao("")
                        .withDocumentos(new ArrayList<>())
                        .withCustos(singletonList(new Custo().withDescricao("").withValor(xml.texto("custoTotalEstimado"))))
                        .withCanaisDePrestacao(
                                Stream.concat(
                                        Stream.of(
                                                new CanalDePrestacao().withTipo("Web").withDescricao(xml.texto("url")).withPreferencial(true),
                                                new CanalDePrestacao().withTipo("Agendamento").withDescricao(xml.texto("urlAgendamento"))
                                        ),
                                        xml.coleta("canaisDePrestacao > canalDePrestacao",
                                                x -> new CanalDePrestacao()
                                                        .withTipo(x.atributo("tipo"))
                                                        .withDescricao(x.atributo("link", "href")))
                                                .stream())
                                        .collect(toList())))));
    }

    private Orgao orgao(ArquivoXml doc) {
        return new Orgao()
                .withId(doc.texto("id"))
                .withNome(doc.texto("nome"));
    }

    private String informacoesUteis(ArquivoXml doc) {
        return doc.coleta("informacoesUteis > informacaoUtil", x ->
                format("* %s%n", x.atributo("link", "href").isEmpty()
                        ? x.texto("descricao")
                        : format("[%s](%s)", x.texto("descricao"), x.atributo("link", "href"))))
                .stream()
                .collect(joining())
                .trim();
    }

}

@@ -564,55 +564,8 @@
 et;%0A
-import static java.util.Collections.emptyList;%0A
 impo
@@ -1997,25 +1997,31 @@
 itantes(
-empt
+new Arra
 yList
+%3C%3E
 ())%0A    
@@ -2087,17 +2087,23 @@
 oes(
-empt
+new Arra
 yList
+%3C%3E
 ())%0A
@@ -2821,16 +2821,32 @@
 hEtapas(
+new ArrayList%3C%3E(
 singleto
@@ -3041,16 +3041,32 @@
 hCustos(
+new ArrayList%3C%3E(
 singleto
@@ -3141,24 +3141,25 @@
 stimado%22))))
+)
 %0A           
@@ -4091,16 +4091,17 @@
 t())))))
+)
 ;%0A    %7D%0A

Usa listas mutáveis