package com.atlassian.bitbucket.mirroring.mirror;

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

/**
 * Represents a remote server that serves as the source for repository mirrors. In the upstream-mirror relationship,
 * this represents the upstream.
 *
 * @since 4.3
 */
public interface UpstreamServer {

    /**
     * @return the account of the team or user that this mirror is associated with on the upstream server
     * or {@link Optional::empty() nothing} if this mirror is not associated with any specific user or team.
     * <p>
     * For {@link UpstreamServerType::BITBUCKET_SERVER Bitbucket Server} this is always empty as the mirror operates
     * for all accounts.
     * <p>
     * For {@link UpstreamServerType::BITBUCKET_CLOUD Bitbucket Cloud} this is the team account the mirror is
     * installed for.
     *
     * @since 4.6
     */
    @Nonnull
    Optional<UpstreamAccount> getAccount();

    /**
     * @return the base of the remote server's URL for REST calls.
     * @since 4.6
     */
    @Nonnull
    String getApiBaseUrl();

    /**
     * @return the remote server's base URL
     */
    @Nonnull
    String getBaseUrl();

    /**
     * @return the identifier for the server
     */
    @Nonnull
    String getId();

    /**
     * @return the date that the last full synchronization with the server successfully completed.
     */
    @Nullable
    Date getLastFullSyncDate();

    /**
     * @return the date that the settings (which project(s) to mirror, and so on) of the server were last changed.
     */
    @Nullable
    Date getLastSettingsChangeDate();

    /**
     * @return the namespace of the server (which appears in clone URLs for repositories mirrored from it)
     */
    @Nonnull
    String getNamespace();

    /**
     * @return the state of the integration with the upstream server
     */
    @Nonnull
    IntegrationState getState();

    /**
     * @return the type of the upstream server.
     * @since 4.6
     */
    @Nonnull
    UpstreamServerType getType();
}
