package ru.yandex.qe.dispenser.api.v1;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import org.jetbrains.annotations.NotNull;

import ru.yandex.qe.dispenser.api.DtoBuilder;
import ru.yandex.qe.dispenser.api.util.JsonDeserializerBase;
import ru.yandex.qe.dispenser.api.util.SerializationUtils;

@JsonDeserialize(using = DiDispenserSettings.Deserializer.class)
public class DiDispenserSettings {
    @NotNull
    private final List<String> admins;

    @NotNull
    public static Builder builder() {
        return new Builder();
    }

    private DiDispenserSettings(@NotNull final BuilderBase<?> builder) {
        this.admins = Collections.unmodifiableList(builder.admins);
    }

    @NotNull
    public List<String> getAdmins() {
        return admins;
    }

    public static abstract class BuilderBase<B extends DiDispenserSettings.BuilderBase<B>> {
        @NotNull
        protected List<String> admins = new ArrayList<>();

        protected BuilderBase() {
        }


        @NotNull
        public B withAdmins(@NotNull final Collection<String> logins) {
            this.admins.addAll(logins);
            return (B) this;
        }

        @NotNull
        public B withAdmins(@NotNull final String... logins) {
            return withAdmins(Arrays.asList(logins));
        }

        protected @NotNull DiDispenserSettings buildDispenser() {
            return new DiDispenserSettings(this);
        }
    }

    public static final class Builder extends BuilderBase<Builder> implements DtoBuilder<DiDispenserSettings> {
        private Builder() {

        }

        @NotNull
        @Override
        public DiDispenserSettings build() {
            return buildDispenser();
        }
    }

    static final class Deserializer extends JsonDeserializerBase<DiDispenserSettings> {
        @NotNull
        @Override
        public DiDispenserSettings deserialize(@NotNull final JsonParser jp,
                                               @NotNull final DeserializationContext dc) throws IOException {
            final JsonNode json = jp.getCodec().readValue(jp, JsonNode.class);
            return builder()
                    .withAdmins(SerializationUtils.convertValue(json.get("admins"), String[].class))
                    .build();
        }
    }
}
