package ai.subut.kurjun.http.apt;


import java.io.IOException;
import java.io.InputStream;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;

import com.google.gson.Gson;
import com.google.inject.Inject;
import com.google.inject.Singleton;

import ai.subut.kurjun.common.service.KurjunContext;
import ai.subut.kurjun.http.HttpServer;
import ai.subut.kurjun.http.HttpServletBase;
import ai.subut.kurjun.metadata.common.DefaultMetadata;
import ai.subut.kurjun.metadata.common.apt.DefaultPackageMetadata;
import ai.subut.kurjun.model.metadata.SerializableMetadata;
import ai.subut.kurjun.model.repository.LocalRepository;
import ai.subut.kurjun.model.security.Permission;
import ai.subut.kurjun.repo.RepositoryFactory;
import ai.subut.kurjun.repo.service.PackageFilenameBuilder;
import ai.subut.kurjun.repo.service.PackageFilenameParser;
import ai.subut.kurjun.security.service.AuthManager;


@Singleton
class AptPoolServlet extends HttpServletBase
{

    @Inject
    private RepositoryFactory repositoryFactory;

    @Inject
    private AuthManager authManager;

    @Inject
    private PackageFilenameParser filenameParser;

    @Inject
    private PackageFilenameBuilder filenameBuilder;

    @Inject
    private Gson gson;


    private KurjunContext context;


    @Override
    public void init() throws ServletException
    {
        this.context = HttpServer.CONTEXT;
    }


    @Override
    protected void doGet( HttpServletRequest req, HttpServletResponse resp ) throws ServletException, IOException
    {
        if ( !checkAuthentication( req, Permission.GET_PACKAGE ) )
        {
            forbidden( resp );
            return;
        }

        String path = "/pool" + req.getPathInfo();
        String packageName = filenameParser.getPackageFromFilename( path );
        String version = filenameParser.getVersionFromFilename( path );
        if ( packageName == null || version == null )
        {
            badRequest( resp, "Invalid pool path" );
            return;
        }

        DefaultMetadata m = new DefaultMetadata();
        m.setName( packageName );
        m.setVersion( version );

        LocalRepository repo = repositoryFactory.createLocalApt( context );
        SerializableMetadata metadata = repo.getPackageInfo( m );

        if ( metadata != null )
        {
            try ( InputStream is = repo.getPackageStream( metadata ) )
            {
                if ( is != null )
                {
                    DefaultPackageMetadata pm = gson.fromJson( metadata.serialize(), DefaultPackageMetadata.class );
                    String filename = filenameBuilder.makePackageFilename( pm );
                    resp.setHeader( "Content-Disposition", "attachment; filename=" + filename );
                    IOUtils.copy( is, resp.getOutputStream() );
                }
                else
                {
                    notFound( resp, "Package file not found" );
                }
            }
        }
        else
        {
            notFound( resp, "Package not found" );
        }
    }


    @Override
    protected KurjunContext getContext()
    {
        return context;
    }


    @Override
    protected AuthManager getAuthManager()
    {
        return authManager;
    }


}


@@ -84,16 +84,54 @@
 tStream;
+%0Aimport java.util.concurrent.TimeUnit;
 %0A%0Aimport
@@ -261,47 +261,8 @@
 e;%0A%0A
-import org.apache.commons.io.IOUtils;%0A%0A
 impo
@@ -319,16 +319,51 @@
 Inject;%0A
+import com.google.inject.Injector;%0A
 import c
@@ -815,24 +815,316 @@
 Permission;%0A
+import ai.subut.kurjun.quota.DataUnit;%0Aimport ai.subut.kurjun.quota.QuotaException;%0Aimport ai.subut.kurjun.quota.QuotaInfoStore;%0Aimport ai.subut.kurjun.quota.QuotaManagerFactory;%0Aimport ai.subut.kurjun.quota.transfer.TransferQuota;%0Aimport ai.subut.kurjun.quota.transfer.TransferQuotaManager;%0A
 import ai.su
@@ -1330,16 +1330,73 @@
 anager;%0A
+import ai.subut.kurjun.storage.factory.FileStoreFactory;%0A
 %0A%0A@Singl
@@ -1724,16 +1724,126 @@
  gson;%0A%0A
+    @Inject%0A    private QuotaManagerFactory quotaManagerFactory;%0A%0A    @Inject%0A    private Injector injector;%0A%0A
 %0A    pri
@@ -1981,16 +1981,496 @@
 CONTEXT;
+%0A%0A        TransferQuota quota = new TransferQuota();%0A        quota.setThreshold( 5 );%0A        quota.setUnit( DataUnit.MB );%0A        quota.setTime( 5 );%0A        quota.setTimeUnit( TimeUnit.MINUTES );%0A%0A        QuotaInfoStore quotaInfoStore = injector.getInstance( QuotaInfoStore.class );%0A        try%0A        %7B%0A            quotaInfoStore.saveTransferQuota( quota, context );%0A        %7D%0A        catch ( IOException ex )%0A        %7B%0A            throw new ServletException( ex );%0A        %7D
 %0A    %7D%0A%0A
@@ -3386,32 +3386,535 @@
 ull )%0A        %7B%0A
+            FileStoreFactory fsFactory = injector.getInstance( FileStoreFactory.class );%0A            long size = fsFactory.create( context ).sizeOf( metadata.getMd5Sum() );%0A%0A            TransferQuotaManager quotaManager = quotaManagerFactory.createTransferQuotaManager( context );%0A            if ( !quotaManager.isAllowedToTransfer( size ) )%0A            %7B%0A                internalServerError( resp, %22Downloading this file will exceed transfer quota threshold.%22 );%0A                return;%0A            %7D%0A%0A
             try 
@@ -4353,15 +4353,20 @@
     
-IOUtils
+quotaManager
 .cop
@@ -4511,32 +4511,32 @@
 e not found%22 );%0A
-
                 
@@ -4543,32 +4543,145 @@
 %7D%0A            %7D%0A
+            catch ( QuotaException ex )%0A            %7B%0A                throw new IOException( ex );%0A            %7D%0A
         %7D%0A      

add quota management to apt servlets