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

import com.atlassian.bitbucket.internal.mirroring.mirror.ExternalRepository;
import com.atlassian.bitbucket.mirroring.mirror.UpstreamAccount;

import javax.annotation.Nonnull;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

import static com.atlassian.bitbucket.internal.mirroring.mirror.rest.cloud.RestCloudEntityProperties.*;
import static java.util.Optional.*;

/**
 * An external repository in BB Cloud with all details available including origin info all the way up the top most
 * repository in the hierarchy.
 */
public class RestCloudExternalRepository extends RestCloudMinimalExternalRepository implements ExternalRepository {

    @SuppressWarnings("unused")
    public RestCloudExternalRepository() {
    }

    public RestCloudExternalRepository(Map<String, ?> values) {
        super(values);
    }

    @Nonnull
    @Override
    public Optional<String> getContentHash() {
        return ofNullable(getStringProperty(UPDATE_ON));
    }

    @SuppressWarnings("unchecked")
    @Nonnull
    @Override
    public Optional<String> getCloneUrl() {
        Map<String, ?> links = (Map<String, ?>) get(LINKS);
        if (links != null) {
            Collection<Map<String, ?>> cloneLinks = (Collection<Map<String, ?>>) links.get(CLONE);
            if (cloneLinks != null) {
                for (Map<String, ?> cloneLink : cloneLinks) {
                    if (HTTPS.equals(cloneLink.get(NAME))) {
                        return ofNullable(Objects.toString(cloneLink.get(HREF), null));
                    }
                }
            }
        }
        return empty();
    }

    @Nonnull
    @Override
    public Optional<ExternalRepository> getOrigin() {
        RestCloudExternalRepository origin = RestCloudExternalRepository.valueOf(get(PARENT));
        if (origin != null && !origin.containsKey(SCM)) {
            origin.put(SCM, getScmId());
        }

        return ofNullable(origin);
    }

    @SuppressWarnings("unchecked")
    @Nonnull
    @Override
    public Optional<UpstreamAccount> getOwner() {
        return of(new RestCloudAccount((Map<String, ?>) get(OWNER)));
    }

    @SuppressWarnings("unchecked")
    public static RestCloudExternalRepository valueOf(Object value) {
        if (value instanceof RestCloudExternalRepository) {
            return (RestCloudExternalRepository) value;
        }
        if (value instanceof Map<?, ?>) {
            return new RestCloudExternalRepository((Map<String, ?>) value);
        }
        return null;
    }
}
