package com.airlock.iam.admin.application.service.permission;

import com.airlock.iam.admin.application.system.AdminappPage;
import com.airlock.iam.admin.application.system.PageUrlMappings;
import com.airlock.iam.core.misc.util.locale.LocaleUtil;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;

public class AdminappPermissionsService {
   private final List<String> startPages;
   private final AdminappPagePermissionsService pagePermissionsService;

   public AdminappPermissionsService.SystemPermissions getPermissions() {
      PagesPermissions pagesPermissions = this.pagePermissionsService.pagesPermissions();
      AdminappPermissions adminappPermissions = AdminappPermissions.builder()
         .global(this.globalPermissions())
         .menu(this.menuPermissions(pagesPermissions))
         .pages(pagesPermissions)
         .build();
      Optional<AdminappPage> startPage = this.getStartPage(pagesPermissions);
      return AdminappPermissionsService.SystemPermissions.builder().adminappPermissions(adminappPermissions).startPage(startPage).build();
   }

   private GlobalPermissions globalPermissions() {
      return GlobalPermissions.builder().back(true).reload(true).globalLicenseWarnings(true).build();
   }

   private Optional<AdminappPage> getStartPage(PagesPermissions permissions) {
      Optional<AdminappPage> startPage = this.startPages
         .stream()
         .map(PageUrlMappings::mapOldPageName)
         .filter(page -> permissions.getPages().get(page.getPageName()) != null && permissions.getPages().get(page.getPageName()).isAccessible())
         .findFirst();
      return startPage.isPresent()
         ? startPage
         : Stream.of(
               AdminappPage.LOGS,
               AdminappPage.USER_LIST,
               AdminappPage.TECH_CLIENT_LIST,
               AdminappPage.MAINTENANCE_MESSAGE_LIST,
               AdminappPage.LICENSE,
               AdminappPage.ADMIN_LIST,
               AdminappPage.OLD_CONFIG_EDITOR,
               AdminappPage.SERVICE_CONTAINER
            )
            .filter(page -> permissions.getPages().get(page.getPageName()) != null && permissions.getPages().get(page.getPageName()).isAccessible())
            .findFirst();
   }

   private MenuPermissions menuPermissions(PagesPermissions pages) {
      MenuPermissions.MenuPermissionsBuilder menu = MenuPermissions.builder();
      pages.getPages()
         .entrySet()
         .stream()
         .filter(entry -> !entry.getKey().endsWith("Detail"))
         .forEach(entry -> menu.permission("menu" + this.capitalizeFirstCharacter(entry.getKey()), entry.getValue().isAccessible()));
      return menu.build();
   }

   private String capitalizeFirstCharacter(String string) {
      return Character.toString(string.charAt(0)).toUpperCase(LocaleUtil.getForSystemStrings()) + string.substring(1);
   }

   @SuppressFBWarnings(justification = "generated code")
   public AdminappPermissionsService(List<String> startPages, AdminappPagePermissionsService pagePermissionsService) {
      this.startPages = startPages;
      this.pagePermissionsService = pagePermissionsService;
   }

   public static class SystemPermissions {
      private AdminappPermissions adminappPermissions;
      private Optional<AdminappPage> startPage;

      @SuppressFBWarnings(justification = "generated code")
      public static AdminappPermissionsService.SystemPermissions.SystemPermissionsBuilder builder() {
         return new AdminappPermissionsService.SystemPermissions.SystemPermissionsBuilder();
      }

      @SuppressFBWarnings(justification = "generated code")
      public AdminappPermissions getAdminappPermissions() {
         return this.adminappPermissions;
      }

      @SuppressFBWarnings(justification = "generated code")
      public Optional<AdminappPage> getStartPage() {
         return this.startPage;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SystemPermissions(AdminappPermissions adminappPermissions, Optional<AdminappPage> startPage) {
         this.adminappPermissions = adminappPermissions;
         this.startPage = startPage;
      }

      @SuppressFBWarnings(justification = "generated code")
      public static class SystemPermissionsBuilder {
         @SuppressFBWarnings(justification = "generated code")
         private AdminappPermissions adminappPermissions;
         @SuppressFBWarnings(justification = "generated code")
         private Optional<AdminappPage> startPage;

         @SuppressFBWarnings(justification = "generated code")
         SystemPermissionsBuilder() {
         }

         @SuppressFBWarnings(justification = "generated code")
         public AdminappPermissionsService.SystemPermissions.SystemPermissionsBuilder adminappPermissions(AdminappPermissions adminappPermissions) {
            this.adminappPermissions = adminappPermissions;
            return this;
         }

         @SuppressFBWarnings(justification = "generated code")
         public AdminappPermissionsService.SystemPermissions.SystemPermissionsBuilder startPage(Optional<AdminappPage> startPage) {
            this.startPage = startPage;
            return this;
         }

         @SuppressFBWarnings(justification = "generated code")
         public AdminappPermissionsService.SystemPermissions build() {
            return new AdminappPermissionsService.SystemPermissions(this.adminappPermissions, this.startPage);
         }

         @SuppressFBWarnings(justification = "generated code")
         @Override
         public String toString() {
            return "AdminappPermissionsService.SystemPermissions.SystemPermissionsBuilder(adminappPermissions="
               + this.adminappPermissions
               + ", startPage="
               + this.startPage
               + ")";
         }
      }
   }
}
