package com.atlassian.bitbucket.internal.mirroring.mirror.rest;

import com.atlassian.bitbucket.mirroring.mirror.IntegrationState;
import com.atlassian.bitbucket.mirroring.mirror.UpstreamServer;
import com.atlassian.bitbucket.mirroring.mirror.UpstreamServerType;
import com.atlassian.bitbucket.rest.RestMapEntity;
import com.atlassian.bitbucket.rest.annotation.JsonSurrogate;
import com.atlassian.bitbucket.rest.util.RestPage;
import com.atlassian.bitbucket.validation.annotation.RequiredString;
import com.google.common.collect.ImmutableList;
import org.codehaus.jackson.map.annotate.JsonSerialize;

import javax.annotation.Nonnull;
import javax.validation.constraints.NotNull;

import static com.atlassian.bitbucket.internal.mirroring.dao.AoConstants.DEFAULT_STRING_COLUMN_LENGTH;
import static com.atlassian.bitbucket.internal.mirroring.dao.AoConstants.LONG_STRING_COLUMN_LENGTH;
import static com.google.common.base.Preconditions.checkNotNull;

@JsonSerialize
@JsonSurrogate(UpstreamServer.class)
public class RestUpstreamServer extends RestMapEntity {

    public static final String APIBASEURL = "apiBaseUrl";
    public static final String BASEURL = "baseUrl";
    public static final String ID = "id";
    public static final String STATE = "state";
    public static final String TYPE = "type";

    private RestUpstreamServer(String id, String baseUrl, String apiBaseUrl, IntegrationState state, UpstreamServerType type) {
        put(ID, id);
        put(APIBASEURL, apiBaseUrl);
        put(BASEURL, baseUrl);
        put(STATE, state.getId());
        put(TYPE, type.getId());
    }

    public RestUpstreamServer(@Nonnull UpstreamServer upstream) {
        this(checkNotNull(upstream, "upstream").getId(), upstream.getBaseUrl(), upstream.getApiBaseUrl(),
                upstream.getState(), upstream.getType());
    }

    @RequiredString(size = LONG_STRING_COLUMN_LENGTH)
    public String getApiBaseUrl() {
        return getStringProperty(APIBASEURL);
    }

    @RequiredString(size = LONG_STRING_COLUMN_LENGTH)
    public String getBaseUrl() {
        return getStringProperty(BASEURL);
    }

    @RequiredString(size = DEFAULT_STRING_COLUMN_LENGTH)
    public String getId() {
        return getStringProperty(ID);
    }

    @NotNull
    public IntegrationState getState() {
        return IntegrationState.fromId(getStringProperty(STATE)).orElse(null);
    }

    @NotNull
    public UpstreamServerType getType() {
        return UpstreamServerType.fromId(getStringProperty(TYPE)).orElseThrow(IllegalStateException::new);
    }

    public static final RestUpstreamServer EXAMPLE_UPSTREAM_SERVER = new RestUpstreamServer(
            "f76a35c5-4592-425d-bf85-b4d9db68e809", "https://bitbucket.company.com", "https://bitbucket.company.com",
            IntegrationState.INSTALLED, UpstreamServerType.BITBUCKET_SERVER);
    public static final RestUpstreamServer EXAMPLE_UPSTREAM_CLOUD = new RestUpstreamServer(
            "f76a35c5-4592-425d-bf85-b4d9db68e809", "https://bitbucket.org", "https://api.bitbucket.org",
            IntegrationState.INSTALLED, UpstreamServerType.BITBUCKET_CLOUD);
    public static final RestPage<RestUpstreamServer> EXAMPLE_PAGE =
            new RestPage<>(0, 25, 1, true, ImmutableList.of(EXAMPLE_UPSTREAM_CLOUD), null);
}
