package controllers;

import java.io.IOException;
import java.net.URISyntaxException;

import javax.servlet.ServletException;

import models.Project;
import models.enumeration.Operation;
import models.enumeration.Resource;

import org.apache.commons.lang.StringUtils;
import org.tigris.subversion.javahl.ClientException;
import org.tmatesoft.svn.core.internal.server.dav.DAVServlet;
import org.tmatesoft.svn.core.internal.server.dav.SVNPathBasedAccess;
import org.tmatesoft.svn.core.internal.server.dav.handlers.DAVHandlerFactory;
import org.tmatesoft.svn.core.internal.util.SVNEncodingUtil;

import play.mvc.*;
import play.mvc.Http.Session;
import playRepository.SVNRepository;
import utils.*;

public class SvnApp extends Controller{
    static DAVServlet davServlet;
    public static final String REPO_PREFIX = "repo/svn/";

    @BodyParser.Of(BodyParser.Raw.class)
    public static Result serviceWithPath(String path) throws ServletException, IOException {
        return service();
    }

    @With(BasicAuthAction.class)
    @BodyParser.Of(BodyParser.Raw.class)
    public static Result service() throws ServletException, IOException {
        //FIXME DAVServlet 들어내고 싶다.
        String path;
        try {
            path = new java.net.URI(request().uri()).getPath();
        } catch (URISyntaxException e) {
            return badRequest();
        }
        String pathInfo = SVNEncodingUtil.uriEncode(path.substring(path.indexOf('/',1)));
        
        String[] pathSegments = pathInfo.substring(1).split("/");

        if (pathSegments.length < 2) {
            return badRequest();
        }

        String userName = pathSegments[0];
        String projectName = pathSegments[1];

        Project project = Project.findByName(projectName);

        if (!AccessControl.isAllowed(session().get(UserApp.SESSION_USERID), project.id,
                Resource.CODE, getRequestedOperation(request().method()), null)) {
            return forbidden("You have no permission to read this repository.");
        }

        pathInfo = pathInfo.substring(pathInfo.indexOf('/', 1));
        PlayServletRequest request = new PlayServletRequest(request(), new PlayServletSession(new PlayServletContext()), pathInfo);
        PlayServletResponse response = new PlayServletResponse(response());

        new SVNRepository(userName, "").getCore().service(request, response);

        response.flushBuffer();

        return status(response.getStatus(), response.getBuffer().toByteArray());
    }

    public static void createRepository(String userName, String projectName) throws ClientException, ServletException {
        new SVNRepository(userName, projectName).create();
    }

    public static String getURL(String ownerName, String projectName) {
        String[] pathSegments = { "svn", ownerName, projectName };
        return Config.getScheme("http") + "://" + Config.getHostport(request().host()) + "/"
                + StringUtils.join(pathSegments, "/");
    }

    public static Result showRawCode(String userName, String projectName, String path) {
        // TODO Auto-generated method stub
        
        return null;
    }

    public static void deleteRepository(String userName, String projectName) throws Exception {
        new SVNRepository(userName, projectName).delete();
        
    }

    private static Operation getRequestedOperation(String method) {
        if (DAVHandlerFactory.METHOD_OPTIONS.equals(method)
                || DAVHandlerFactory.METHOD_PROPFIND.equals(method)
                || DAVHandlerFactory.METHOD_GET.equals(method)
                || DAVHandlerFactory.METHOD_REPORT.equals(method)) {
            return Operation.READ;
        } else {
            return Operation.WRITE;
        }
    }

}

@@ -380,78 +380,8 @@
 et;%0A
-import org.tmatesoft.svn.core.internal.server.dav.SVNPathBasedAccess;%0A
 impo
@@ -657,16 +657,17 @@
 ntroller
+ 
 %7B%0A    st
@@ -753,16 +753,49 @@
 svn/%22;%0A%0A
+    @With(BasicAuthAction.class)%0A
     @Bod
@@ -1111,16 +1111,17 @@
       //
+ 
 FIXME DA
@@ -1321,24 +1321,25 @@
       %7D%0A
+%0A
         
 String p
@@ -1334,87 +1334,130 @@
     
-String pathInfo = SVNEncodingUtil.uriEncode(path.substring(path.indexOf('/',1))
+// If the url starts with slash, remove the slash.%0A        if (path.startsWith(%22/%22)) %7B%0A            path = path.substring(1
 );%0A 
@@ -1455,32 +1455,34 @@
 ing(1);%0A        
+%7D%0A
 %0A        String%5B
@@ -1478,53 +1478,104 @@
     
-String%5B%5D pathSegments = pathInfo.substring(1)
+// Split the url into three segments: %22svn%22, userName, pathInfo%0A        String%5B%5D segments = path
 .spl
@@ -1580,20 +1580,22 @@
 plit(%22/%22
+, 3
 );%0A
-%0A
         
@@ -1598,21 +1598,17 @@
     if (
-pathS
+s
 egments.
@@ -1620,9 +1620,9 @@
 h %3C 
-2
+3
 ) %7B%0A
@@ -1636,34 +1636,33 @@
      return 
-badRequest
+forbidden
 ();%0A        
@@ -1676,39 +1676,131 @@
     
-String userName = pathS
+// Get userName and pathInfo from path segments.%0A        String userName = segments%5B1%5D;%0A        String pathInfo = s
 egments%5B
 0%5D;%0A
@@ -1799,58 +1799,185 @@
 nts%5B
-0%5D;%0A        String projectName = pathSegments%5B1%5D;%0A
+2%5D;%0A%0A        // Get projectName from the pathInfo.%0A        String projectName = pathInfo.split(%22/%22, 2)%5B0%5D;%0A%0A        // Check the user has a permission to access this repository.
 %0A   
@@ -2017,17 +2017,35 @@
 ndByName
-(
+AndOwner(userName, 
 projectN
@@ -2046,25 +2046,24 @@
 ojectName);%0A
-%0A
         if (
@@ -2281,12 +2281,14 @@
  to 
-read
+access
  thi
@@ -2327,64 +2327,122 @@
     
-pathInfo = pathInfo.substring(pathInfo.indexOf('/', 1));
+// Transform request and response in this context to ServletRequest and%0A        // ServletResponse for DAVServlet.
 %0A   
@@ -2532,16 +2532,33 @@
 Session(
+%0A                
 new Play
@@ -2576,16 +2576,42 @@
 ext()), 
+SVNEncodingUtil.uriEncode(
 pathInfo
@@ -2611,16 +2611,17 @@
 athInfo)
+)
 ;%0A      
@@ -2687,24 +2687,101 @@
 sponse());%0A%0A
+        // Get DAVServlet from SVNRepository and serve the request using it.%0A
         new 

Fix the access control that occurs error.