package com.atlassian.bitbucket.internal.mirroring.upstream.rest;

import com.atlassian.bitbucket.internal.mirroring.upstream.InternalMirrorServer;
import com.atlassian.bitbucket.internal.mirroring.upstream.InternalMirrorService;
import com.atlassian.bitbucket.internal.mirroring.MirroringConstants;
import com.atlassian.bitbucket.permission.Permission;
import com.atlassian.bitbucket.permission.PermissionValidationService;
import com.atlassian.bitbucket.rest.util.ResponseFactory;
import com.atlassian.bitbucket.server.ApplicationMode;
import com.atlassian.bitbucket.server.ApplicationModeSupplier;
import com.atlassian.plugin.web.WebInterfaceManager;
import com.atlassian.plugin.web.descriptors.WebPanelModuleDescriptor;
import com.google.common.collect.ImmutableMap;
import org.apache.commons.lang3.StringUtils;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.Optional;

import static java.util.Optional.ofNullable;

@Path("mirrorServers/{mirrorId}/webPanels")
public class WebPanelResource {
    private final ApplicationModeSupplier supplier;
    private final InternalMirrorService mirrorService;
    private final PermissionValidationService permissionValidationService;
    private final WebInterfaceManager webInterfaceManager;

    public WebPanelResource(ApplicationModeSupplier supplier,
                            InternalMirrorService mirrorService,
                            PermissionValidationService permissionValidationService,
                            WebInterfaceManager webInterfaceManager) {
        this.webInterfaceManager = webInterfaceManager;
        this.mirrorService = mirrorService;
        this.permissionValidationService = permissionValidationService;
        this.supplier = supplier;
    }

    /**
     * This renders the HTML that is needed to get the remote connect web-panel on the mirror.
     */
    @Produces(MediaType.TEXT_HTML)
    @GET
    @Path("config")
    public Response get(@PathParam("mirrorId") String mirrorId) {

        if (supplier.getMode() != ApplicationMode.DEFAULT) {
            return ResponseFactory.notFound().build();
        }

        permissionValidationService.validateForGlobal(Permission.ADMIN);

        return ofNullable(mirrorService.getById(mirrorId))
                .flatMap(this::getPanelHtmlFor)
                .map(ResponseFactory::ok)
                .orElseGet(ResponseFactory::notFound)
                .build();
    }

    private Optional<String> getPanelHtmlFor(InternalMirrorServer server) {
        String addonKey = server.getAddonKey();
        return webInterfaceManager.getWebPanelDescriptors(MirroringConstants.LOCATION_CONFIG_PANEL).stream()
                .filter(descriptor -> StringUtils.startsWith(descriptor.getKey(), addonKey))
                .findAny()
                .map(WebPanelModuleDescriptor::getModule)
                .map(panel -> panel.getHtml(ImmutableMap.of()));
    }
}
