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.apache.causeway.core.config.beans;
  
  import java.io.Serializable;
  
  import org.apache.causeway.applib.id.LogicalType;
  import org.apache.causeway.applib.services.metamodel.BeanSort;
  import org.apache.causeway.commons.internal.base._Strings;
  
  import org.jspecify.annotations.NonNull;
  
  public record CausewayBeanMetaData(
          @NonNull LogicalType logicalType,
          @NonNull BeanSort beanSort,
          @NonNull DiscoveredBy discoveredBy,
          @NonNull ManagedBy managedBy,
          @NonNull PersistenceStack persistenceStack)
  implements Serializable {
  
      public enum PersistenceStack {
          NONE,
          JDBC,
          JPA,
          JDO,
          /**
           * eg. abstract entity type
           */
          UNSPECIFIED;
          public boolean isNone() { return this == NONE; }
          public boolean isJdbc() { return this == JDBC; }
          public boolean isJpa() { return this == JPA; }
          public boolean isJdo() { return this == JDO; }
          public boolean isUnspecified() { return this == UNSPECIFIED; }
          public boolean isPresent() { return this == JDBC || this == JPA || this == JDO; }
  
          public String titleCase() {
              return _Strings.capitalize(_Strings.lower(name()));
          }
      }
  
      public enum DiscoveredBy {
          CAUSEWAY_UPFRONT,
          CAUSEWAY_ONTHEFLY,
          SPRING;
          //boolean isCauseway() { return this == CAUSEWAY; }
          //boolean isCausewayTest() { return this == CAUSEWAY_LAZY; }
          boolean isSpring() { return this == SPRING; }
      }
  
      public enum ManagedBy {
          NONE,
          CAUSEWAY,
          SPRING,
          PERSISTENCE,
          /** other Spring managed component, or not managed at all */
          UNSPECIFIED;
          public boolean isNone() { return this == NONE; }
          public boolean isCauseway() { return this == CAUSEWAY; }
          public boolean isSpring() { return this == SPRING; }
          public boolean isPersistence() { return this == PERSISTENCE; }
          public boolean isUnspecified() { return this == UNSPECIFIED; }
      }
  
      public Class<?> getCorrespondingClass() {
          return logicalType.correspondingClass();
      }
  
      public String getBeanName() {
          return logicalType.logicalName();
      }
  
      // -- FACTORIES
  
      public static CausewayBeanMetaData vetoed(
              final @NonNull LogicalType logicalType,
              final @NonNull DiscoveredBy discoveredBy) {
          return new CausewayBeanMetaData(logicalType, BeanSort.VETOED, discoveredBy, ManagedBy.NONE, PersistenceStack.NONE);
      }
      public static CausewayBeanMetaData value(
              final @NonNull LogicalType logicalType,
              final @NonNull DiscoveredBy discoveredBy) {
          return new CausewayBeanMetaData(logicalType, BeanSort.VALUE, discoveredBy, ManagedBy.NONE, PersistenceStack.NONE);
      }
      public static CausewayBeanMetaData collection(
              final @NonNull LogicalType logicalType,
              final @NonNull DiscoveredBy discoveredBy) {
          return new CausewayBeanMetaData(logicalType, BeanSort.COLLECTION, discoveredBy, ManagedBy.CAUSEWAY, PersistenceStack.NONE);
      }
      public static CausewayBeanMetaData interfaceOrAbstract(
              final @NonNull LogicalType logicalType,
              final @NonNull DiscoveredBy discoveredBy) {
          return new CausewayBeanMetaData(logicalType, BeanSort.ABSTRACT, discoveredBy, ManagedBy.UNSPECIFIED, PersistenceStack.NONE);
      }
      public static CausewayBeanMetaData viewModel(
              final @NonNull LogicalType logicalType,
              final @NonNull DiscoveredBy discoveredBy) {
          return new CausewayBeanMetaData(logicalType, BeanSort.VIEW_MODEL, discoveredBy, ManagedBy.CAUSEWAY, PersistenceStack.NONE);
      }
      public static CausewayBeanMetaData entity(
              final @NonNull LogicalType logicalType,
              final @NonNull DiscoveredBy discoveredBy,
              final @NonNull PersistenceStack persistenceStack) {
          return new CausewayBeanMetaData(logicalType, BeanSort.ENTITY, discoveredBy, ManagedBy.PERSISTENCE, persistenceStack);
      }
      public static CausewayBeanMetaData mixin(
              final @NonNull LogicalType logicalType,
              final @NonNull DiscoveredBy discoveredBy) {
          return new CausewayBeanMetaData(logicalType, BeanSort.MIXIN, discoveredBy, ManagedBy.CAUSEWAY, PersistenceStack.NONE);
      }
      public static CausewayBeanMetaData programmatic(
              final @NonNull LogicalType logicalType) {
          return new CausewayBeanMetaData(logicalType, BeanSort.PROGRAMMATIC, DiscoveredBy.CAUSEWAY_ONTHEFLY, ManagedBy.CAUSEWAY, PersistenceStack.NONE);
      }
      public static CausewayBeanMetaData springContributing(
              final @NonNull LogicalType logicalType) {
          return new CausewayBeanMetaData(logicalType, BeanSort.MANAGED_BEAN_CONTRIBUTING, DiscoveredBy.SPRING, ManagedBy.SPRING, PersistenceStack.NONE);
      }
      public static CausewayBeanMetaData springNotContributing(
              final @NonNull LogicalType logicalType) {
          return new CausewayBeanMetaData(logicalType, BeanSort.MANAGED_BEAN_NOT_CONTRIBUTING, DiscoveredBy.SPRING, ManagedBy.SPRING, PersistenceStack.NONE);
      }
      /**
       * If discovered by Spring, let Spring decide whether it wants to manage this type.
       */
      public static CausewayBeanMetaData unspecified(
              final @NonNull LogicalType logicalType,
              final @NonNull DiscoveredBy discoveredBy,
              final @NonNull BeanSort beanSort) {
          return new CausewayBeanMetaData(logicalType, beanSort, discoveredBy, ManagedBy.UNSPECIFIED, PersistenceStack.NONE);
      }
  
  }
  