package com.atlassian.bitbucket.mesh.git;

import com.atlassian.bitbucket.mesh.git.cache.PackCacheService;
import com.atlassian.bitbucket.mesh.repository.Repository;
import com.atlassian.bitbucket.mesh.repository.RepositoryManager;
import com.atlassian.bitbucket.mesh.rpc.v1.*;
import com.atlassian.util.contentcache.CacheStatistics;
import com.atlassian.util.contentcache.ContentCacheStatistics;
import io.grpc.stub.StreamObserver;

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

public class GrpcPackCacheService extends PackCacheServiceGrpc.PackCacheServiceImplBase {

    private final PackCacheService packCacheService;
    private final RepositoryManager repositoryManager;

    public GrpcPackCacheService(PackCacheService packCacheService, RepositoryManager repositoryManager) {
        this.packCacheService = packCacheService;
        this.repositoryManager = repositoryManager;
    }

    @Override
    public void clear(RpcClearPackCacheRequest request, StreamObserver<RpcClearPackCacheResponse> responseObserver) {
        if (request.hasRepository()) {
            Repository repository = repositoryManager.getById(request.getRepository());
            if (isNotEmpty(request.getCacheKey())) {
                packCacheService.clear(repository, request.getCacheKey());
            } else {
                packCacheService.clear(repository);
            }
        } else {
            packCacheService.clear();
        }

        responseObserver.onNext(RpcClearPackCacheResponse.getDefaultInstance());
        responseObserver.onCompleted();
    }

    @Override
    public void getStatistics(RpcGetPackCacheStatisticsRequest request,
                              StreamObserver<RpcGetPackCacheStatisticsResponse> responseObserver) {
        RpcGetPackCacheStatisticsResponse response;
        if (request.hasRepository()) {
            Repository repository = repositoryManager.getById(request.getRepository());
            ContentCacheStatistics statistics = packCacheService.getStatistics(repository);
            if (statistics == null) {
                response = RpcGetPackCacheStatisticsResponse.getDefaultInstance();
            } else {
                response = RpcGetPackCacheStatisticsResponse.newBuilder()
                        .setHits(statistics.getHits())
                        .setMisses(statistics.getMisses())
                        .setSize(statistics.getSize())
                        .build();
            }
        } else {
            CacheStatistics statistics = packCacheService.getStatistics();
            response = RpcGetPackCacheStatisticsResponse.newBuilder()
                    .setHits(statistics.getHits())
                    .setMisses(statistics.getMisses())
                    .setSize(statistics.getSize())
                    .build();
        }
        responseObserver.onNext(response);
        responseObserver.onCompleted();
    }
}
