package com.atlassian.stash.internal.scm.git.submodule;

import com.atlassian.bitbucket.nav.NavBuilder;

import javax.annotation.Nonnull;
import java.net.URI;

import static org.apache.commons.lang3.StringUtils.removeEnd;

/**
 * @since 2.3
 */
class DefaultGitSubmoduleUriHandler implements GitSubmoduleUriHandler {

    private final NavBuilder navBuilder;

    public DefaultGitSubmoduleUriHandler(NavBuilder navBuilder) {
        this.navBuilder = navBuilder;
    }

    @Nonnull
    @Override
    public SubmoduleUrls process(@Nonnull URI uri, @Nonnull String contentId) {
        if (isSameUriBestGuess(URI.create(navBuilder.buildBaseUrl()), uri)) {
            String[] parts = uri.getPath().split("/");
            if (parts.length > 2) { // First part is always blank due to leading slash
                NavBuilder.Repo repo = navBuilder.project(parts[parts.length - 2]).repo(removeEnd(parts[parts.length - 1], ".git"));
                return new SubmoduleUrls(repo.buildAbsolute(), repo.browse().atRevision(contentId).buildAbsolute());
            }
        }
        return SubmoduleUrls.NONE;
    }

    /**
     * Attempts to guess whether {@code uri} is from <i>this</i> host. This will be more accurate for HTTP than for
     * SSH, as we don't know what port the latter is configured on. This may result in false positives if the host
     * is being used to serve multiple Stash instances. SSH may also be configured on a different host, in which case
     * we will never be able to match them. This will be possible to handle "properly" when
     * <a href="https://jira.atlassian.com/browse/STASH-3160">STASH-3160</a> is implemented.
     */
    private boolean isSameUriBestGuess(URI baseUrl, URI uri) {
        return baseUrl.getHost().equals(uri.getHost()) && (
                (uri.getPort() == baseUrl.getPort() && uri.getPath().startsWith(baseUrl.getPath())) ||
                        uri.getScheme().equals("ssh")
        );
    }
}
