package com.atlassian.stash.internal.web.markup;

import com.atlassian.markup.renderer.MarkupRendererComponent;
import com.atlassian.markup.renderer.RenderContext;
import com.atlassian.markup.renderer.RenderTransform;
import com.atlassian.stash.internal.web.attach.AttachmentUri;
import com.atlassian.bitbucket.nav.NavBuilder;
import com.atlassian.bitbucket.repository.Repository;
import com.atlassian.bitbucket.repository.RepositorySupplier;
import com.google.common.collect.Multimap;

import javax.annotation.Nonnull;
import java.util.Collection;
import java.util.Map;
import java.util.function.Function;
import java.util.regex.MatchResult;

import static com.atlassian.bitbucket.util.MarkupUtils.findMatches;

/**
 * Replaces URIs of the form "attachment:{repoId}/{encodedAttachmentId}" (as returned by
 * {@link com.atlassian.stash.internal.web.attach.AttachmentController}) with a resolved HTTP/HTTPS URL of the form
 * "{BASE_URL}/projects/{projectKey}/repos/{repoSlug}/attachments/{attachmentId}".
 *
 * @since 3.8
 */
public class AttachmentMarkupRenderer implements MarkupRendererComponent {

    private final NavBuilder navBuilder;
    private final RepositorySupplier repositorySupplier;

    public AttachmentMarkupRenderer(NavBuilder navBuilder, RepositorySupplier repositorySupplier) {
        this.navBuilder = navBuilder;
        this.repositorySupplier = repositorySupplier;
    }

    @Nonnull
    @Override
    public RenderTransform process(@Nonnull CharSequence text, @Nonnull RenderContext context) {
        RenderTransform.TransformBuilder builder = RenderTransform.builder();

        Map<String, Collection<MatchResult>> matches = findMatches(text, AttachmentUri.PATTERN, null);
        for (Collection<MatchResult> matchResults : matches.values()) {
            for (MatchResult match : matchResults) {
                AttachmentUri attachmentUri = AttachmentUri.from(match);
                if (attachmentUri == null) {
                    continue;
                }

                Repository repository = repositorySupplier.getById(attachmentUri.getRepositoryId());
                if (repository == null) {
                    continue;
                }

                String url = navBuilder.repo(repository)
                        .attachments()
                        .attachment(attachmentUri.getAttachmentId())
                        .buildRelNoContext();
                String hostUrl = context.createHostUrl(url);

                builder.add(match.start(), match.end(), hostUrl);
            }
        }

        return builder.build();
    }

}
