package com.ctrip.zeus.restful.resource;

import com.ctrip.zeus.auth.Authorize;
import com.ctrip.zeus.lock.DbLockFactory;
import com.ctrip.zeus.lock.DistLock;
import com.ctrip.zeus.service.activate.ActivateService;
import com.ctrip.zeus.service.build.BuildInfoService;
import com.ctrip.zeus.service.build.BuildService;
import com.ctrip.zeus.service.model.GroupRepository;
import com.ctrip.zeus.service.model.SlbRepository;
import com.ctrip.zeus.service.nginx.NginxService;
import com.ctrip.zeus.util.AssertUtils;
import com.netflix.config.DynamicBooleanProperty;
import com.netflix.config.DynamicIntProperty;
import com.netflix.config.DynamicPropertyFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * Created by fanqq on 2015/3/20.
 */

@Component
@Path("/conf")
public class ActivateResource {

    @Resource
    private ActivateService activateConfService;
    @Resource
    private NginxService nginxAgentService;
    @Resource
    private BuildInfoService buildInfoService;
    @Resource
    private BuildService buildService;
    @Resource
    private DbLockFactory dbLockFactory;
    @Resource
    private SlbRepository slbRepository;
    @Resource
    private GroupRepository groupRepository;


    private static DynamicIntProperty lockTimeout = DynamicPropertyFactory.getInstance().getIntProperty("lock.timeout", 5000);
    private static DynamicBooleanProperty writable = DynamicPropertyFactory.getInstance().getBooleanProperty("activate.writable", true);



//    @GET
//    @Path("/activateByName")
//    @Authorize(name="activate")
//    public Response activateByName(@Context HttpServletRequest request,@Context HttpHeaders hh,@QueryParam("slbName") List<String> slbNames,  @QueryParam("groupName") List<String> groupNames)throws Exception{
//        List<Long> slbIds = new ArrayList<>();
//        List<Long> groupIds = new ArrayList<>();
//        for (String slbName : slbNames)
//        {
//            slbIds.add(slbRepository.get(slbName).getId());
//        }
//        for (String groupName : groupNames)
//        {
//            groupIds.add(groupRepository.get(groupName).getId());
//        }
//
//        return activateAll(slbIds,groupIds,hh);
//    }
//
//    @GET
//    @Path("/activate")
//    @Authorize(name="activate")
//    public Response activateById(@Context HttpServletRequest request,@Context HttpHeaders hh,@QueryParam("slbId") List<Long> slbIds,  @QueryParam("groupId") List<Long> groupIds)throws Exception{
//        return activateAll(slbIds,groupIds,hh);
//    }

    @GET
    @Path("/activate/slb")
    @Authorize(name="activate")
    public Response activateSlb(@Context HttpServletRequest request,@Context HttpHeaders hh,@QueryParam("slbId") List<Long> slbIds,  @QueryParam("slbName") List<String> slbNames)throws Exception{
        List<Long> _groupIds = new ArrayList<>();
        List<Long> _slbIds = new ArrayList<>();

        if ( slbIds!=null && !slbIds.isEmpty() )
        {
            _slbIds.addAll(slbIds);
        }
        if ( slbNames!=null && !slbNames.isEmpty() )
        {
            for (String slbName : slbNames)
            {
                _slbIds.add(slbRepository.get(slbName).getId());
            }
        }
        return activateAll(_slbIds,_groupIds,hh);
    }

    @GET
    @Path("/activate/group")
    @Authorize(name="activate")
    public Response activateGroup(@Context HttpServletRequest request,@Context HttpHeaders hh,@QueryParam("groupId") List<Long> groupIds,  @QueryParam("groupName") List<String> groupNames)throws Exception{
        List<Long> _groupIds = new ArrayList<>();
        List<Long> _slbIds = new ArrayList<>();

        if ( groupIds!=null && !groupIds.isEmpty() )
        {
            _groupIds.addAll(groupIds);
        }
        if ( groupNames!=null && !groupNames.isEmpty() )
        {
            for (String groupName : groupNames)
            {
                _groupIds.add(groupRepository.get(groupName).getId());
            }
        }
        return activateAll(_slbIds,_groupIds,hh);
    }


    private Response activateAll(List<Long> slbIds,List<Long> groupIds, HttpHeaders hh)throws Exception{

        AssertUtils.arrertNotEquels(0,slbIds.size()+groupIds.size(),"slbIds list and groupIds list are empty!");

        //update active action to conf-slb-active and conf-app-active
        activateConfService.activate(slbIds,groupIds);

        //find all slbs which need build config
        Set<Long> slbList = buildInfoService.getAllNeededSlb(slbIds, groupIds);

        if (slbList.size() > 0)
        {
            //build all slb config
            for (Long buildSlbId : slbList) {
                int ticket = buildInfoService.getTicket(buildSlbId);
                boolean buildFlag = false;
                DistLock buildLock = dbLockFactory.newLock( "build_" + buildSlbId);
                try{
                    buildLock.lock(lockTimeout.get());
                    buildFlag =buildService.build(buildSlbId,ticket);
                }finally {
                    buildLock.unlock();
                }
                if (buildFlag && writable.get()) {
                    DistLock writeLock = dbLockFactory.newLock( "writeAndReload_" +  buildSlbId);
                    try {
                        writeLock.lock(lockTimeout.get());
                        //Push Service
                        nginxAgentService.writeAllAndLoadAll(buildSlbId);

                    } finally {
                        writeLock.unlock();
                    }
                }
            }
            return Response.ok().status(200).build();
        }else
        {
            return Response.status(200).type(hh.getMediaType()).entity("No slb need activate!please check your config").build();
        }


    }
}

@@ -1102,20 +1102,24 @@
 @Path(%22/
-conf
+activate
 %22)%0Apubli
@@ -1821,1053 +1821,8 @@
 );%0A%0A
-%0A%0A//    @GET%0A//    @Path(%22/activateByName%22)%0A//    @Authorize(name=%22activate%22)%0A//    public Response activateByName(@Context HttpServletRequest request,@Context HttpHeaders hh,@QueryParam(%22slbName%22) List%3CString%3E slbNames,  @QueryParam(%22groupName%22) List%3CString%3E groupNames)throws Exception%7B%0A//        List%3CLong%3E slbIds = new ArrayList%3C%3E();%0A//        List%3CLong%3E groupIds = new ArrayList%3C%3E();%0A//        for (String slbName : slbNames)%0A//        %7B%0A//            slbIds.add(slbRepository.get(slbName).getId());%0A//        %7D%0A//        for (String groupName : groupNames)%0A//        %7B%0A//            groupIds.add(groupRepository.get(groupName).getId());%0A//        %7D%0A//%0A//        return activateAll(slbIds,groupIds,hh);%0A//    %7D%0A//%0A//    @GET%0A//    @Path(%22/activate%22)%0A//    @Authorize(name=%22activate%22)%0A//    public Response activateById(@Context HttpServletRequest request,@Context HttpHeaders hh,@QueryParam(%22slbId%22) List%3CLong%3E slbIds,  @QueryParam(%22groupId%22) List%3CLong%3E groupIds)throws Exception%7B%0A//        return activateAll(slbIds,groupIds,hh);%0A//    %7D%0A%0A
     
@@ -1838,25 +1838,16 @@
 @Path(%22/
-activate/
 slb%22)%0A  
@@ -2568,17 +2568,8 @@
 h(%22/
-activate/
 grou

update api