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

import java.io.IOException;

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

import ru.yandex.qe.dispenser.api.util.JsonDeserializerBase;
import ru.yandex.qe.dispenser.api.util.JsonSerializerBase;
import ru.yandex.qe.dispenser.api.util.ValidationUtils;

@JsonSerialize(using = DiPerformer.Serializer.class)
@JsonDeserialize(using = DiPerformer.Deserializer.class)
public final class DiPerformer {
    @NotNull
    private final String login;
    @NotNull
    private final String projectKey;

    private DiPerformer(@NotNull final Builder builder) {
        login = builder.login;
        projectKey = ValidationUtils.requireNonNull(builder.projectKey, "Project key is required!");
    }

    @NotNull
    public static Builder login(@NotNull final String login) {
        return new Builder(login);
    }

    @NotNull
    public String getLogin() {
        return login;
    }

    @NotNull
    public String getProjectKey() {
        return projectKey;
    }

    @Override
    public String toString() {
        return "DiPerformer{project=" + projectKey + ", person=" + login + '}';
    }

    public static class Builder {
        @NotNull
        private final String login;
        @Nullable
        private String projectKey;

        public Builder(@NotNull final String login) {
            this.login = login;
        }

        @NotNull
        public DiPerformer chooses(@NotNull final String projectKey) {
            this.projectKey = projectKey;
            return new DiPerformer(this);
        }


    }

    static class Serializer extends JsonSerializerBase<DiPerformer> {
        @Override
        public void serialize(@NotNull final DiPerformer performer,
                              @NotNull final JsonGenerator jg,
                              @NotNull final SerializerProvider sp) throws IOException {
            jg.writeStartObject();
            jg.writeStringField("login", performer.getLogin());
            jg.writeStringField("projectKey", performer.getProjectKey());
            jg.writeEndObject();
        }
    }

    static class Deserializer extends JsonDeserializerBase<DiPerformer> {
        @NotNull
        @Override
        public DiPerformer deserialize(@NotNull final JsonParser jp,
                                       @NotNull final DeserializationContext dc) throws IOException {
            final JsonNode json = toJson(jp);
            return login(json.get("login").asText()).chooses(json.get("projectKey").asText());
        }
    }
}
