package com.atlassian.bitbucket.scm.cache.rest;

import com.atlassian.bitbucket.NoSuchEntityException;
import com.atlassian.bitbucket.i18n.I18nService;
import com.atlassian.bitbucket.i18n.KeyedMessage;
import com.atlassian.bitbucket.repository.NoSuchRepositoryException;
import com.atlassian.bitbucket.repository.Repository;
import com.atlassian.bitbucket.repository.RepositoryService;
import com.atlassian.bitbucket.rest.util.ResponseFactory;
import com.atlassian.bitbucket.rest.util.RestUtils;
import com.atlassian.bitbucket.scm.cache.ScmCacheService;
import com.atlassian.plugins.rest.common.security.AnonymousAllowed;
import com.atlassian.util.contentcache.CacheStatistics;
import com.atlassian.util.contentcache.ContentCacheStatistics;
import com.sun.jersey.spi.resource.Singleton;

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

@AnonymousAllowed
@Consumes({MediaType.APPLICATION_JSON})
@Produces({RestUtils.APPLICATION_JSON_UTF8})
@Singleton
@Path("caches")
public class ScmCacheResource {

    private final ScmCacheService cacheService;
    private final I18nService i18nService;
    private final RepositoryService repositoryService;

    public ScmCacheResource(ScmCacheService cacheService, I18nService i18nService,
                            RepositoryService repositoryService) {
        this.cacheService = cacheService;
        this.i18nService = i18nService;
        this.repositoryService = repositoryService;
    }

    @DELETE
    public Response clear() {
        cacheService.clear();

        return ResponseFactory.noContent().build();
    }

    @DELETE
    @Path("{projectKey}/{repositorySlug}")
    public Response clearRegion(@PathParam("projectKey") String projectKey, @PathParam("repositorySlug") String repoSlug) {
        cacheService.clear(getRepository(projectKey, repoSlug));

        return ResponseFactory.noContent().build();
    }

    @DELETE
    @Path("{projectKey}/{repositorySlug}/{cacheKey}")
    public Response clearRegion(@PathParam("projectKey") String projectKey, @PathParam("repositorySlug") String repoSlug,
                                @PathParam("cacheKey") String cacheKey) {
        cacheService.clear(getRepository(projectKey, repoSlug), cacheKey);

        return ResponseFactory.noContent().build();
    }

    @GET
    public Response getStatus() {
        CacheStatistics status = cacheService.getStatistics();

        return ResponseFactory.ok().entity(new RestCacheStatistics(status)).build();
    }

    @GET
    @Path("{projectKey}/{repositorySlug}")
    public Response getStatus(@PathParam("projectKey") String projectKey, @PathParam("repositorySlug") String repoSlug) {
        ContentCacheStatistics status = cacheService.getStatistics(getRepository(projectKey, repoSlug));
        if (status == null) {
            throw new NoSuchEntityException(i18nService.createKeyedMessage("plugin.scm-cache.nosuchregion", projectKey, repoSlug));
        }

        return ResponseFactory.ok().entity(new RestCacheContentStatistics(status)).build();
    }

    private Repository getRepository(String projectKey, String repoSlug) {
        Repository repository = repositoryService.getBySlug(projectKey, repoSlug);
        if (repository == null) {
            KeyedMessage message = i18nService.createKeyedMessage("plugin.scm-cache.nosuchrepository", projectKey, repoSlug);

            throw new NoSuchRepositoryException(message, null);
        }
        return repository;
    }
}
