package com.sagacloud.filters;

import com.google.common.base.Strings;
import com.sagacloud.json.JSONArray;
import com.sagacloud.json.JSONObject;
import com.sagacloud.json.JSONValue;
import com.sagacloud.utils.Const;
import com.sagacloud.utils.DpUtils;
import com.sagacloud.utils.OssUtils;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Priority;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Priority(3)
@Provider
public class AccessibilityRequestFilter implements ContainerRequestFilter {
    private static final Logger log = LoggerFactory.getLogger(AccessibilityRequestFilter.class);

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
        if (OssUtils.getProperty("api.access.needpsw").trim().equalsIgnoreCase("false")) {
            return;
        }

        Map paraMap = requestContext.getUriInfo().getQueryParameters();
        String proId = Strings.nullToEmpty(((List<String>) paraMap.get("projectId")) == null ? null : ((List<String>) paraMap.get("projectId")).get(0));
        String urlPath = requestContext.getUriInfo().getPath();
        if (urlPath.startsWith("dict") || urlPath.startsWith("doc")
                || urlPath.startsWith("infocode") || urlPath.startsWith("mng") || urlPath.startsWith("calendar")) {
            return;
        }
        boolean access = true;
        InputStream bodyStream = requestContext.getEntityStream();
//        log.info("REQUEST URL: {} {}", requestContext.getUriInfo().getPath(), requestContext.getUriInfo().getPathParameters());
        StringWriter writer = new StringWriter();
        try {
            String[] keys = {"building_id", "floor_id", "id", "from_id", "to_id", "bound_obj_id", "building"};
            IOUtils.copy(bodyStream, writer, "utf-8");
            JSONObject json = (JSONObject) JSONValue.parse(writer.toString());
            if (json == null) {
                return;
            }
//            log.info("REQUEST BODY2: {}", json.toString());
            ArrayList<String> idList = new ArrayList<>();
            if (json.containsKey("criteria")) {//单条操作时
                JSONObject criteria = (JSONObject) json.get("criteria");
                for (String key : keys) {
                    if (criteria.containsKey(key) && criteria.get(key) != null) {
                        idList.add(criteria.get(key).toString());
                    }
                }
                if (json.containsKey("set")) {
                    JSONObject set = (JSONObject) json.get("set");
                    for (String key : keys) {
                        if (set.containsKey(key) && set.get(key) != null) {
                            idList.add(set.get(key).toString());
                        }
                    }
                }
            } else if (json.containsKey("criterias")) {//批量操作时
                JSONArray criterias = (JSONArray) json.get("criterias");
                for (int i = 0; i < criterias.size(); ++i) {
                    JSONObject item = (JSONObject) criterias.get(i);
                    for (String key : keys) {
                        if (item.containsKey(key) && item.get(key) != null) {
                            idList.add(item.get(key).toString());
                        }
                    }
                }
                if (json.containsKey("sets")) {
                    JSONArray sets = (JSONArray) json.get("sets");
                    for (int i = 0; i < sets.size(); ++i) {
                        JSONObject item = (JSONObject) sets.get(i);
                        for (String key : keys) {
                            if (item.containsKey(key) && item.get(key) != null) {
                                idList.add(item.get(key).toString());
                            }
                        }
                    }
                }
            } else {//创建时
                for (String key : keys) {
                    if (json.containsKey(key) && json.get(key) != null) {
                        idList.add(json.get(key).toString());
                    }
                }
            }

            for (String id : idList) {
                if (id.startsWith(Const.OBJ_TYPE_PROPERTY))//对资产不做校验
                    continue;
                String pj;
                try {
                    if (id.startsWith("VO"))
                        pj = id.substring(4, 14);
                    else
                        pj = id.substring(2, 12);
                    if (!pj.equals(proId.substring(2, 12))) {
                        access = false;
                        break;
                    }
                } catch (Exception e) {
                    access = false;
                    break;
                }
            }

            if (!access) {
                requestContext.abortWith(Response
                        .status(Response.Status.UNAUTHORIZED)
                        .entity(DpUtils.errorJsonMsg("你没有权限操作其他项目下的内容！"))
                        .build());
            }

            requestContext.setEntityStream(new ByteArrayInputStream(writer.toString().getBytes()));
//            System.out.println(writer.toString());

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
