content: /*
   *
   *  Licensed to the Apache Software Foundation (ASF) under one or more
   *  contributor license agreements.  See the NOTICE file distributed with
   *  this work for additional information regarding copyright ownership.
   *  The ASF licenses this file to You under the Apache License, Version 2.0
   *  (the "License"); you may not use this file except in compliance with
   *  the License.  You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   *  Unless required by applicable law or agreed to in writing, software
   *  distributed under the License is distributed on an "AS IS" BASIS,
   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   *  See the License for the specific language governing permissions and
   *  limitations under the License.
   *
   */
  
  package org.dinky.controller;
  
  import org.dinky.data.annotations.Log;
  import org.dinky.data.constant.PermissionConstants;
  import org.dinky.data.enums.BusinessType;
  import org.dinky.data.enums.Status;
  import org.dinky.data.model.udf.UDFTemplate;
  import org.dinky.data.result.ProTableResult;
  import org.dinky.data.result.Result;
  import org.dinky.service.UDFTemplateService;
  
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  import java.util.Set;
  
  import org.springframework.transaction.annotation.Transactional;
  import org.springframework.web.bind.annotation.DeleteMapping;
  import org.springframework.web.bind.annotation.GetMapping;
  import org.springframework.web.bind.annotation.PostMapping;
  import org.springframework.web.bind.annotation.PutMapping;
  import org.springframework.web.bind.annotation.RequestBody;
  import org.springframework.web.bind.annotation.RequestMapping;
  import org.springframework.web.bind.annotation.RequestParam;
  import org.springframework.web.bind.annotation.RestController;
  
  import com.fasterxml.jackson.databind.JsonNode;
  
  import cn.dev33.satoken.annotation.SaCheckPermission;
  import cn.dev33.satoken.annotation.SaMode;
  import cn.hutool.core.collection.CollUtil;
  import cn.hutool.core.lang.Dict;
  import cn.hutool.core.util.StrUtil;
  import io.swagger.annotations.Api;
  import io.swagger.annotations.ApiImplicitParam;
  import io.swagger.annotations.ApiOperation;
  import lombok.RequiredArgsConstructor;
  import lombok.extern.slf4j.Slf4j;
  
  /** UDFTemplateController */
  @Slf4j
  @Api(tags = "UDF Controller")
  @RestController
  @RequestMapping("/api/udf/template")
  @RequiredArgsConstructor
  public class UDFTemplateController {
  
      private final UDFTemplateService udfTemplateService;
  
      /**
       * build udf tree
       *
       * @return
       */
      @GetMapping("/tree")
      @ApiOperation("Build UDF Tree")
      public Result<List<Object>> listUdfTemplates() {
          List<UDFTemplate> list = udfTemplateService.list();
          Map<String, Dict> one = new HashMap<>(3);
          Map<String, Dict> two = new HashMap<>(3);
          Map<String, Dict> three = new HashMap<>(3);
          Map<String, Object> result = new HashMap<>(3);
          list.forEach(t -> {
              one.putIfAbsent(
                      t.getCodeType(), Dict.create().set("label", t.getCodeType()).set("value", t.getCodeType()));
              two.putIfAbsent(
                      t.getCodeType() + t.getFunctionType(),
                      Dict.create().set("label", t.getFunctionType()).set("value", t.getFunctionType()));
              three.putIfAbsent(
                      t.getCodeType() + t.getFunctionType() + t.getId(),
                      Dict.create().set("label", t.getName()).set("value", t.getId()));
          });
          Set<String> twoKeys = two.keySet();
          Set<String> threeKeys = three.keySet();
          one.forEach((k1, v1) -> {
              result.put(k1, v1);
              ArrayList<Dict> c1 = new ArrayList<>();
              v1.put("children", c1);
              twoKeys.stream()
                      .filter(x -> x.contains(k1))
                      .map(x -> StrUtil.strip(x, k1))
                      .forEach(k2 -> {
                          Dict v2 = two.get(k1 + k2);
                          c1.add(v2);
                          ArrayList<Dict> c2 = new ArrayList<>();
                          v2.put("children", c2);
                          threeKeys.stream()
                                  .filter(x -> x.contains(k1 + k2))
                                  .map(x -> StrUtil.strip(x, k1 + k2))
                                  .forEach(k3 -> {
                                      c2.add(three.get(k1 + k2 + k3));
                                  });
                      });
          });
          return Result.succeed(CollUtil.newArrayList(result.values()));
      }
  
      /**
       * get udf template list
       *
       * @param params {@link JsonNode}
       * @return {@link ProTableResult} <{@link UDFTemplate}>
       */
      @PostMapping("/list")
      @ApiOperation("Get UDF Template List")
      @ApiImplicitParam(
              name = "params",
              value = "ProTable Params",
              dataType = "JsonNode",
              paramType = "body",
              required = true)
      public ProTableResult<UDFTemplate> listUdfTemplates(@RequestBody JsonNode params) {
          return udfTemplateService.selectForProTable(params);
      }
  
      /**
       * save or update udf template
       *
       * @param udfTemplate {@link UDFTemplate}
       * @return {@link Result} <{@link String}>
       */
      @PutMapping
      @ApiOperation("Insert or Update UDF Template")
      @Log(title = "Insert or Update UDF Template", businessType = BusinessType.INSERT_OR_UPDATE)
      @ApiImplicitParam(
              name = "udfTemplate",
              value = "UDF Template",
              dataType = "UDFTemplate",
              paramType = "body",
              required = true)
      @SaCheckPermission(
              value = {
                  PermissionConstants.REGISTRATION_UDF_TEMPLATE_ADD,
                  PermissionConstants.REGISTRATION_UDF_TEMPLATE_EDIT
              },
              mode = SaMode.OR)
      public Result<String> saveOrUpdateUDFTemplate(@RequestBody UDFTemplate udfTemplate) {
          return udfTemplateService.saveOrUpdate(udfTemplate)
                  ? Result.succeed(Status.SAVE_SUCCESS)
                  : Result.failed(Status.SAVE_FAILED);
      }
  
      /**
       * delete udf template by id
       *
       * @param id {@link Integer}
       * @return {@link Result} <{@link Void}>
       */
      @DeleteMapping("/delete")
      @Log(title = "Delete UDF Template By Id", businessType = BusinessType.DELETE)
      @ApiOperation("Delete UDF Template By Id")
      @ApiImplicitParam(
              name = "id",
              value = "UDF Template Id",
              dataType = "Integer",
              paramType = "query",
              required = true)
      @SaCheckPermission(PermissionConstants.REGISTRATION_UDF_TEMPLATE_DELETE)
      @Transactional(rollbackFor = Exception.class)
      public Result<Void> deleteUDFTemplate(@RequestParam Integer id) {
          if (udfTemplateService.removeById(id)) {
              return Result.succeed(Status.DELETE_SUCCESS);
          } else {
              return Result.failed(Status.DELETE_FAILED);
          }
      }
  
      @PutMapping("/enable")
      @ApiOperation("Modify UDF Template Status")
      @Log(title = "Modify UDF Template Status", businessType = BusinessType.UPDATE)
      @ApiImplicitParam(
              name = "id",
              value = "UDF Template Id",
              dataType = "Integer",
              paramType = "query",
              required = true)
      @SaCheckPermission(PermissionConstants.REGISTRATION_UDF_TEMPLATE_EDIT)
      public Result<Void> modifyUDFTemplateStatus(@RequestParam Integer id) {
          if (udfTemplateService.modifyUDFTemplateStatus(id)) {
              return Result.succeed(Status.MODIFY_SUCCESS);
          } else {
              return Result.failed(Status.MODIFY_FAILED);
          }
      }
  }
  