package com.atlassian.bitbucket.mesh.management;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

import javax.annotation.Nonnull;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import static java.util.Objects.requireNonNull;

public class SupportInfoRegistry implements BeanPostProcessor {

    private static final Logger log = LoggerFactory.getLogger(SupportInfoRegistry.class);

    private final List<SupportInfoProvider> providers;

    public SupportInfoRegistry() {
        providers = new ArrayList<>();
    }

    @Override
    public Object postProcessAfterInitialization(@Nonnull Object bean, @Nonnull String beanName) throws BeansException {
        if (bean instanceof SupportInfoProvider) {
            providers.add((SupportInfoProvider) bean);
        }
        return bean;
    }

    public void writeSupportInfo(@Nonnull OutputStream outputStream) throws IOException {
        requireNonNull(outputStream, "outputStream");

        try (JsonGenerator json = new ObjectMapper()
                .registerModule(new JavaTimeModule())
                .createGenerator(outputStream)
                .useDefaultPrettyPrinter()) {
            json.writeStartObject();
            try {
                for (SupportInfoProvider provider : providers) {
                    try {
                        provider.writeSupportInfo(json);
                    } catch (RuntimeException e) {
                        log.warn("Skipping failed support info provider", e);
                    }
                }
            } finally {
                json.writeEndObject();
            }
        }
    }
}
