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

import com.atlassian.bitbucket.internal.mirroring.mirror.InternalUpstreamServer;
import com.atlassian.bitbucket.mirroring.mirror.IntegrationState;
import com.atlassian.bitbucket.mirroring.mirror.UpstreamAccount;
import com.atlassian.bitbucket.mirroring.mirror.UpstreamServerType;
import net.java.ao.*;
import net.java.ao.schema.*;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Date;
import java.util.Optional;

import static com.atlassian.bitbucket.internal.mirroring.dao.AoConstants.*;

/**
 * ActiveObjects entity that represents an upstream server that is a source for repository mirrors
 */
@Table(AoUpstreamServer.TABLE_NAME)
@Preload
@Implementation(DelegatingUpstreamServer.class)
public interface AoUpstreamServer extends InternalUpstreamServer, RawEntity<String> {

    String TABLE_NAME = "UPSTREAM_SERVER";

    /**
     * @since 4.6
     */
    @Ignore
    @Nonnull
    @Override
    Optional<UpstreamAccount> getAccount();

    /**
     * @since 4.6
     */
    @Accessor(UPSTREAM_ACCOUNT_ID)
    @StringLength(DEFAULT_STRING_COLUMN_LENGTH)
    String getAccountId();

    /**
     * @since 4.6
     */
    @Accessor(UPSTREAM_ACCOUNT_NAME)
    @StringLength(DEFAULT_STRING_COLUMN_LENGTH)
    String getAccountName();

    /**
     * @since 4.6
     */
    @NotNull
    @Override
    @Accessor(API_URL_COLUMN)
    @StringLength(LONG_STRING_COLUMN_LENGTH)
    String getApiBaseUrl();

    @Override
    @NotNull
    @Unique
    @Accessor(BASE_URL_COLUMN)
    @StringLength(LONG_STRING_COLUMN_LENGTH)
    String getBaseUrl();

    @Nonnull
    @Ignore
    @Override
    Optional<String> getIssuerId();

    @Accessor(ISSUER_ID_COLUMN)
    @StringLength(DEFAULT_STRING_COLUMN_LENGTH)
    String getIssuerIdRaw();

    @Override
    @NotNull
    @PrimaryKey(ID_COLUMN)
    @StringLength(DEFAULT_STRING_COLUMN_LENGTH)
    String getId();

    @Override
    @Accessor(LAST_SETTINGS_CHANGE_DATE_COLUMN)
    Date getLastSettingsChangeDate();

    @Override
    @Accessor(LAST_FULL_SYNC_DATE_COLUMN)
    Date getLastFullSyncDate();

    @Override
    @NotNull
    @Unique
    @Accessor(NAMESPACE_COLUMN)
    @StringLength(DEFAULT_STRING_COLUMN_LENGTH)
    String getNamespace();

    @Nonnull
    @Override
    @Ignore
    Optional<String> getSharedSecret();

    @Indexed
    @Accessor(SHARED_SECRET_COLUMN)
    @StringLength(LONG_STRING_COLUMN_LENGTH)
    String getSharedSecretRaw();

    @Override
    @NotNull
    @Accessor(STATE_COLUMN)
    IntegrationState getState();

    /**
     * @since 4.6
     */
    @NotNull
    @Override
    @Accessor(PRODUCT_TYPE_COLUMN)
    UpstreamServerType getType();

    /**
     * @param account the ID of the upstream account that is being mirrored. Only relevant for cloud and will be null on
     *                server.
     * @since 4.6
     */
    @Mutator(UPSTREAM_ACCOUNT_ID)
    void setAccountId(@Nullable String account);

    /**
     * @param account the name of the upstream account that is being mirrored. Only relevant for cloud and will be null on
     *                server.
     * @since 4.6
     */
    @Mutator(UPSTREAM_ACCOUNT_NAME)
    void setAccountName(@Nullable String account);

    /**
     * @param apiBaseUrl the base of the REST API.
     * @since 4.6
     */
    @Mutator(API_URL_COLUMN)
    void setApiBaseUrl(@Nonnull String apiBaseUrl);

    void setIssuerId(@Nonnull String issuerId);

    @Override
    @Mutator(LAST_FULL_SYNC_DATE_COLUMN)
    void setLastFullSyncDate(@Nullable Date lastFullSyncDate);

    @Override
    @Mutator(LAST_SETTINGS_CHANGE_DATE_COLUMN)
    void setLastSettingsChangeDate(@Nullable Date lastSettingsChangeDate);

    @Mutator(NAMESPACE_COLUMN)
    void setNamespace(@Nonnull String namespace);

    @Mutator(SHARED_SECRET_COLUMN)
    void setSharedSecret(@Nonnull String sharedSecret);

    @Mutator(STATE_COLUMN)
    void setState(@Nonnull IntegrationState state);
}
