class ResourceRequestBuilder {

    private static Map<String, Object> getResourceInput(String resourceInputStr, Map<String, Object> uuiRequestInputs,
            ResourceLevel resourceLevel, Map<String, Object> currentVFData) {
        try {
            Gson gson = new Gson();
            Type type = new TypeToken<Map<String, String>>() {}.getType();
            Map<String, Object> resourceInput = gson.fromJson(resourceInputStr, type);
            JsonParser parser = new JsonParser();

            Map<String, Object> uuiServiceInput = uuiRequestInputs;

            int firstLevelIndex = 0;
            int secondLevelIndex = 0;
            String firstLevelKey = null;
            String secondLevelKey = null;
            boolean levelKeyNameUpdated = false;
            int indexToPick = 0;

            if (null != currentVFData) {
                firstLevelIndex = getIntValue(currentVFData.get("currentFirstLevelIndex"), 0);
                secondLevelIndex = getIntValue(currentVFData.get("currentSecondLevelIndex"), 0);
                final String lastFirstLevelKey = firstLevelKey = (String) currentVFData.get("currentFirstLevelKey");
                final String lastSecondLevelKey = secondLevelKey = (String) currentVFData.get("currentSecondLevelKey");

                if (null != currentVFData.get("lastNodeTypeProcessed")) {
                    ResourceLevel lastResourceLevel =
                            ResourceLevel.valueOf(currentVFData.get("lastNodeTypeProcessed").toString());
                    switch (resourceLevel) {
                        case FIRST:
                            // if it is next request for same group then increment first level index
                            boolean isSameLevelRequest = resourceInput.values().stream().anyMatch(item -> {
                                JsonElement tree = parser.parse(((String) item).split("\\|")[0]);
                                return tree.isJsonArray() && tree.getAsJsonArray().get(0).getAsString()
                                        .equalsIgnoreCase(lastFirstLevelKey);
                            });
                            if (isSameLevelRequest) {
                                firstLevelIndex++;
                            } else {
                                firstLevelIndex = 0;
                            }
                            if (lastResourceLevel == ResourceLevel.SECOND) {
                                secondLevelKey = null;
                            }
                            indexToPick = firstLevelIndex;
                            break;
                        case SECOND:
                            // if it is next request for same group then increment second level index
                            switch (lastResourceLevel) {
                                case FIRST:
                                    secondLevelIndex = 0;
                                    break;
                                case SECOND:
                                    boolean isSameSecondLevelRequest =
                                            resourceInput.values().stream().anyMatch(item -> {
                                                JsonElement tree = parser.parse(((String) item).split("\\|")[0]);
                                                return tree.isJsonArray() && tree.getAsJsonArray().get(0).getAsString()
                                                        .equalsIgnoreCase(lastSecondLevelKey);
                                            });
                                    if (isSameSecondLevelRequest) {
                                        secondLevelIndex++;
                                    }
                                    break;
                            }
                            // get actual parent object to search for second level objects
                            if (null != lastFirstLevelKey) {
                                Object currentObject = uuiRequestInputs.get(lastFirstLevelKey);
                                if ((null != currentObject) && (currentObject instanceof List)) {
                                    List currentFirstLevelList = (List) currentObject;
                                    if (currentFirstLevelList.size() > firstLevelIndex) {
                                        uuiServiceInput =
                                                (Map<String, Object>) currentFirstLevelList.get(firstLevelIndex);
                                    }

                                }
                            }
                            indexToPick = secondLevelIndex;
                            break;

                    }
                }


            }

            // replace value if key is available in service input
            for (String key : resourceInput.keySet()) {
                String value = (String) resourceInput.get(key);

                if (value.contains("|")) {

                    // check which level

                    // node it type of getinput
                    String[] split = value.split("\\|");
                    String tmpKey = split[0];

                    JsonElement jsonTree = parser.parse(tmpKey);

                    // check if it is a list type
                    if (jsonTree.isJsonArray()) {
                        JsonArray jsonArray = jsonTree.getAsJsonArray();
                        boolean matchFound = false;
                        if (jsonArray.size() == 3) {
                            String keyName = jsonArray.get(0).getAsString();
                            String keyType = jsonArray.get(2).getAsString();
                            if (!levelKeyNameUpdated) {
                                switch (resourceLevel) {
                                    case FIRST:
                                        firstLevelKey = keyName;
                                        break;
                                    case SECOND:
                                        secondLevelKey = keyName;
                                        break;
                                }
                                levelKeyNameUpdated = true;
                            }

                            if ((null != uuiServiceInput) && (uuiServiceInput.containsKey(keyName))) {
                                Object vfcLevelObject = uuiServiceInput.get(keyName);
                                // it will be always list
                                if (vfcLevelObject instanceof List) {
                                    List vfcObject = (List) vfcLevelObject;
                                    if (vfcObject.size() > indexToPick) {
                                        Map<String, Object> vfMap = (Map<String, Object>) vfcObject.get(indexToPick);
                                        if (vfMap.containsKey(keyType)) {
                                            if (vfMap.get(keyType) instanceof String) {
                                                value = (String) vfMap.get(keyType);
                                            } else {
                                                value = getJsonString(vfMap.get(keyType));
                                            }
                                            matchFound = true;
                                        }
                                    }
                                }
                            }
                        }

                        if (!matchFound) {
                            if (split.length == 1) { // means value is empty e.g. "a":"key1|"
                                value = "";
                            } else {
                                value = split[1];
                            }
                        }

                    } else {

                        // if not a list type
                        if ((null != uuiServiceInput) && (uuiServiceInput.containsKey(tmpKey))) {
                            value = (String) uuiServiceInput.get(tmpKey);
                        } else {
                            if (split.length == 1) { // means value is empty e.g. "a":"key1|"
                                value = "";
                            } else {
                                value = split[1];
                            }
                        }
                    }

                }
                resourceInput.put(key, value);
            }
            // store current processed details into map
            if (null != currentVFData) {
                currentVFData.put("currentFirstLevelKey", firstLevelKey);
                currentVFData.put("currentFirstLevelIndex", firstLevelIndex);
                currentVFData.put("currentSecondLevelKey", secondLevelKey);
                currentVFData.put("currentSecondLevelIndex", secondLevelIndex);
                currentVFData.put("lastNodeTypeProcessed", resourceLevel.toString());
            }

            return resourceInput;

        } catch (Exception e) {
            logger.error("not able to parse and modify service resource input value against UUI ", e);
        }
        return new HashMap();
    }

    private  ResourceRequestBuilder();

}