/*
* 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.directory.scim.server.provider;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.Instance;
import jakarta.inject.Inject;
import jakarta.xml.bind.annotation.XmlEnumValue;

import org.apache.directory.scim.server.ScimConfiguration;
import org.apache.directory.scim.server.exception.InvalidProviderException;
import org.apache.directory.scim.server.exception.UnableToRetrieveExtensionsResourceException;
import org.apache.directory.scim.server.schema.Registry;
import org.apache.directory.scim.spec.annotation.ScimAttribute;
import org.apache.directory.scim.spec.annotation.ScimExtensionType;
import org.apache.directory.scim.spec.annotation.ScimResourceIdReference;
import org.apache.directory.scim.spec.annotation.ScimResourceType;
import org.apache.directory.scim.spec.annotation.ScimType;
import org.apache.directory.scim.spec.exception.ScimResourceInvalidException;
import org.apache.directory.scim.spec.extension.ScimExtensionRegistry;
import org.apache.directory.scim.spec.resources.BaseResource;
import org.apache.directory.scim.spec.resources.ScimExtension;
import org.apache.directory.scim.spec.resources.ScimResource;
import org.apache.directory.scim.spec.schema.ResourceType;
import org.apache.directory.scim.spec.schema.Schema;
import org.apache.directory.scim.spec.schema.Schema.Attribute;
import org.apache.directory.scim.spec.schema.Schema.Attribute.AddAction;
import org.apache.directory.scim.spec.schema.Schema.Attribute.Type;

import com.fasterxml.jackson.core.JsonProcessingException;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;

@Data
@Slf4j
@ApplicationScoped
public class ProviderRegistry implements ScimConfiguration {

  private static final String STRING_TYPE_IDENTIFIER = "class java.lang.String";
  private static final String CHARACTER_ARRAY_TYPE_IDENTIFIER = "class [C";
  private static final String BIG_C_CHARACTER_ARRAY_TYPE_IDENTIFIER = "class [Ljava.lang.Character;";
  private static final String INT_TYPE_IDENTIFIER = "int";
  private static final String INTEGER_TYPE_IDENTIFIER = "class java.lang.Integer";
  private static final String FLOAT_TYPE_IDENTIFIER = "float";
  private static final String BIG_F_FLOAT_TYPE_IDENTIFIER = "class java.lang.Float";
  private static final String DOUBLE_TYPE_IDENTIFIER = "double";
  private static final String BIG_D_DOUBLE_TYPE_IDENTIFIER = "class java.lang.Double";
  private static final String BOOLEAN_TYPE_IDENTIFIER = "boolean";
  private static final String BIG_B_BOOLEAN_TYPE_IDENTIFIER = "class java.lang.Boolean";
  private static final String LOCAL_TIME_TYPE_IDENTIFER = "class java.time.LocalTime";
  private static final String LOCAL_DATE_TYPE_IDENTIFER = "class java.time.LocalDate";
  private static final String LOCAL_DATE_TIME_TYPE_IDENTIFIER = "class java.time.LocalDateTime";
  private static final String DATE_TYPE_IDENTIFIER = "class java.util.Date";
  private static final String BYTE_ARRAY_TYPE_IDENTIFIER = "class [B";
  private static final String RESOURCE_REFERENCE_TYPE_IDENTIFIER = "class org.apache.directory.scim.spec.schema.ResourceReference$ReferenceType";

  private Registry registry;

  private ScimExtensionRegistry scimExtensionRegistry;

  // Weld needs the '? extends' or the providers will not be found, some CDI
  // implementations work fine with just <ScimResources>
  private Instance<Provider<? extends ScimResource>> scimProviderInstances;

  private Map<Class<? extends ScimResource>, Provider<? extends ScimResource>> providerMap = new HashMap<>();

  @Inject
  public ProviderRegistry(Registry registry, ScimExtensionRegistry scimExtensionRegistry, Instance<Provider<? extends ScimResource>> scimProviderInstances) {
    this.registry = registry;
    this.scimExtensionRegistry = scimExtensionRegistry;
    this.scimProviderInstances = scimProviderInstances;
  }

  ProviderRegistry() {}

  @Override
  @SuppressWarnings("unchecked")
  public void configure() {
    scimProviderInstances.stream()
      .map(provider -> (Provider<ScimResource>) provider)
      .forEach(provider -> {
      try {
        registerProvider(provider.getResourceClass(), provider);
      } catch (InvalidProviderException | JsonProcessingException | UnableToRetrieveExtensionsResourceException e) {
        throw new ScimResourceInvalidException("Failed to register provider " + provider.getClass() + " for ScimResource type " + provider.getResourceClass(), e);
      }
    });
  }

  public synchronized <T extends ScimResource> void registerProvider(Class<T> clazz, Provider<T> provider) throws InvalidProviderException, JsonProcessingException, UnableToRetrieveExtensionsResourceException {

    ResourceType resourceType = generateResourceType(clazz, provider);

    log.info("Calling addSchema on the base class: {}", clazz);
    registry.addSchema(generateBaseSchema(clazz));
    // NOTE generateResourceType() ensures ScimResourceType exists
    ScimResourceType scimResourceType = clazz.getAnnotation(ScimResourceType.class);
    String schemaUrn = scimResourceType.schema();
    String endpoint = scimResourceType.endpoint();
    registry.addScimResourceSchemaUrn(schemaUrn, clazz);
    registry.addScimResourceEndPoint(endpoint, clazz);

    List<Class<? extends ScimExtension>> extensionList = provider.getExtensionList();

    if (extensionList != null) {
      for (Class<? extends ScimExtension> scimExtension : extensionList) {
        log.info("Registering a extension of type: " + scimExtension);
        scimExtensionRegistry.registerExtension(clazz, scimExtension);
        
        log.info("Calling addSchema on an extension: " + scimExtension);
        registry.addSchema(generateExtensionSchema(scimExtension));
      }
    }

    registry.addResourceType(resourceType);
    providerMap.put(clazz, provider);
  }

  @SuppressWarnings("unchecked")
  public <T extends ScimResource> Provider<T> getProvider(Class<T> clazz) {
    return (Provider<T>) providerMap.get(clazz);
  }

  private ResourceType generateResourceType(Class<? extends ScimResource> base, Provider<? extends ScimResource> provider) throws InvalidProviderException, UnableToRetrieveExtensionsResourceException {

    ScimResourceType scimResourceType = base.getAnnotation(ScimResourceType.class);

    if (scimResourceType == null) {
      throw new InvalidProviderException("Missing annotation: ScimResourceType must be at the top of scim resource classes");
    }

    ResourceType resourceType = new ResourceType();
    resourceType.setDescription(scimResourceType.description());
    resourceType.setId(scimResourceType.id());
    resourceType.setName(scimResourceType.name());
    resourceType.setEndpoint(scimResourceType.endpoint());
    resourceType.setSchemaUrn(scimResourceType.schema());

    List<Class<? extends ScimExtension>> extensionList = provider.getExtensionList();

    if (extensionList != null) {

      List<ResourceType.SchemaExtentionConfiguration> extensionSchemaList = new ArrayList<>();

      for (Class<? extends ScimExtension> se : extensionList) {

        ScimExtensionType extensionType = se.getAnnotation(ScimExtensionType.class);

        if (extensionType == null) {
          throw new InvalidProviderException("Missing annotation: ScimExtensionType must be at the top of scim extension classes");
        }

        ResourceType.SchemaExtentionConfiguration ext = new ResourceType.SchemaExtentionConfiguration();
        ext.setRequired(extensionType.required());
        ext.setSchemaUrn(extensionType.id());
        extensionSchemaList.add(ext);
      }

      resourceType.setSchemaExtensions(extensionSchemaList);
    }

    return resourceType;
  }

  public static Schema generateSchema(Class<? extends ScimResource> clazz) throws InvalidProviderException {
    return generateBaseSchema(clazz);
  }

  private static Schema generateBaseSchema(Class<?> clazz) throws InvalidProviderException {
    List<Field> fieldList = ReflectionUtils.getFieldsUpTo(clazz, BaseResource.class);

    return generateSchema(clazz, fieldList);
  }
  
  public static Schema generateExtensionSchema(Class<?> clazz) throws InvalidProviderException {
    log.debug("----> In generateExtensionSchema");
    
    return generateSchema(clazz, ReflectionUtils.getFieldsUpTo(clazz, Object.class));
  }
  
  private static Schema generateSchema(Class<?> clazz, List<Field> fieldList) throws InvalidProviderException {

    // Field [] fieldList = clazz.getDeclaredFields();

    Schema schema = new Schema();

    ScimResourceType srt = clazz.getAnnotation(ScimResourceType.class);
    ScimExtensionType set = clazz.getAnnotation(ScimExtensionType.class);

    if (srt == null && set == null) {
      // TODO - throw?
      log.error("Neither a ScimResourceType or ScimExtensionType annotation found");
    }

    log.debug("calling set attributes with " + fieldList.size() + " fields");
    String urn = set != null ? set.id() : srt.schema();
    Set<String> invalidAttributes = new HashSet<>();
    List<Attribute> createAttributes = createAttributes(urn, fieldList, invalidAttributes, clazz.getSimpleName());
    schema.setAttributes(createAttributes);

    if (!invalidAttributes.isEmpty()) {
      StringBuilder sb = new StringBuilder();

      sb.append("Scim attributes cannot be primitive types unless they are required.  The following values were found that are primitive and not required\n\n");

      for (String s : invalidAttributes) {
        sb.append(s);
        sb.append("\n");
      }

      throw new InvalidProviderException(sb.toString());
    }

    if (srt != null) {
      schema.setId(srt.schema());
      schema.setDescription(srt.description());
      schema.setName(srt.name());
    } else {
      schema.setId(set.id());
      schema.setDescription(set.description());
      schema.setName(set.name());
    }

    return schema;
  }

  private static List<Attribute> createAttributes(String urn, List<Field> fieldList, Set<String> invalidAttributes, String nameBase) throws InvalidProviderException {
    List<Attribute> attributeList = new ArrayList<>();

    for (Field f : fieldList) {
      ScimAttribute sa = f.getAnnotation(ScimAttribute.class);

      log.debug("++++++++++++++++++++ Processing field " + f.getName());
      if (sa == null) {
        log.debug("Attribute " + f.getName() + " did not have a ScimAttribute annotation");
        continue;
      }

      String attributeName;
      f.setAccessible(true);

      if (sa.name() == null || sa.name().isEmpty()) {
        attributeName = f.getName();
      } else {
        attributeName = sa.name();
      }

      if (f.getType().isPrimitive() && !sa.required()) {
        invalidAttributes.add(nameBase + "." + attributeName);
        continue;
      }

      //TODO - Fix this to look for the two types of canonical attributes
      Attribute attribute = new Attribute();
      attribute.setAccessor(Schema.AttributeAccessor.forField(f));
      attribute.setName(attributeName);
      attribute.setUrn(urn);
      
      List<String> canonicalTypes = null;
      Field [] enumFields = sa.canonicalValueEnum().getFields();
      log.debug("Gathered fields of off the enum, there are " + enumFields.length + " " + sa.canonicalValueEnum().getName());
      
      if (enumFields.length != 0) {
        
        //This looks goofy, but there's always at least the default value, so it's not an empty list
        if (sa.canonicalValueList().length != 1 && !sa.canonicalValueList()[0].isEmpty()) {
          throw new InvalidProviderException("You cannont set both the canonicalEnumValue and canonicalValueList attributes on the same ScimAttribute");
        }
        
        canonicalTypes = new ArrayList<>();

        for (Field field : enumFields) {
          XmlEnumValue [] annotation = field.getAnnotationsByType(XmlEnumValue.class);
          
          if (annotation.length != 0) {
            canonicalTypes.add(annotation[0].value());
          } else {
            canonicalTypes.add(field.getName());
          }
        }
      } else {
        canonicalTypes = Arrays.asList(sa.canonicalValueList());
      }

      // If we just have the default single empty string, set to null
      if (canonicalTypes.isEmpty() || (canonicalTypes.size() == 1 && canonicalTypes.get(0).isEmpty())) {
        attribute.setCanonicalValues(null);
      } else {
        attribute.setCanonicalValues(new HashSet<String>(canonicalTypes));
      }

      attribute.setCaseExact(sa.caseExact());
      attribute.setDescription(sa.description());

      String typeName = null;
      if (Collection.class.isAssignableFrom(f.getType())) {
        log.debug("We have a collection");
        ParameterizedType stringListType = (ParameterizedType) f.getGenericType();
        Class<?> attributeContainedClass = (Class<?>) stringListType.getActualTypeArguments()[0];
        typeName = attributeContainedClass.getTypeName();
        attribute.setMultiValued(true);
      } else if (f.getType().isArray()) {
        log.debug("We have an array");
        Class<?> componentType = f.getType().getComponentType();
        typeName = componentType.getTypeName();
        attribute.setMultiValued(true);
      } else {
        typeName = f.getType().toString();
        attribute.setMultiValued(false);
      }

      // attribute.setType(sa.type());
      boolean attributeIsAString = false;
      log.debug("Attempting to set the attribute type, raw value = " + typeName);
      switch (typeName) {
      case STRING_TYPE_IDENTIFIER:
      case CHARACTER_ARRAY_TYPE_IDENTIFIER:
      case BIG_C_CHARACTER_ARRAY_TYPE_IDENTIFIER:
        log.debug("Setting type to String");
        attribute.setType(Type.STRING);
        attributeIsAString = true;
        break;
      case INT_TYPE_IDENTIFIER:
      case INTEGER_TYPE_IDENTIFIER:
        log.debug("Setting type to integer");
        attribute.setType(Type.INTEGER);
        break;
      case FLOAT_TYPE_IDENTIFIER:
      case BIG_F_FLOAT_TYPE_IDENTIFIER:
      case DOUBLE_TYPE_IDENTIFIER:
      case BIG_D_DOUBLE_TYPE_IDENTIFIER:
        log.debug("Setting type to decimal");
        attribute.setType(Type.DECIMAL);
        break;
      case BOOLEAN_TYPE_IDENTIFIER:
      case BIG_B_BOOLEAN_TYPE_IDENTIFIER:
        log.debug("Setting type to boolean");
        attribute.setType(Type.BOOLEAN);
        break;
      case BYTE_ARRAY_TYPE_IDENTIFIER:
        log.debug("Setting type to binary");
        attribute.setType(Type.BINARY);
        break;
      case DATE_TYPE_IDENTIFIER:
      case LOCAL_DATE_TIME_TYPE_IDENTIFIER:
      case LOCAL_TIME_TYPE_IDENTIFER:
      case LOCAL_DATE_TYPE_IDENTIFER:
        log.debug("Setting type to date time");
        attribute.setType(Type.DATE_TIME);
        break;
      case RESOURCE_REFERENCE_TYPE_IDENTIFIER:
        log.debug("Setting type to reference");
        attribute.setType(Type.REFERENCE);
        break;
      default:
        log.debug("Setting type to complex");
        attribute.setType(Type.COMPLEX);
      }
      if (f.getAnnotation(ScimResourceIdReference.class) != null) {
        if (attributeIsAString) {
          attribute.setScimResourceIdReference(true);
        } else {
          log.warn("Field annotated with @ScimResourceIdReference must be a string: {}", f);
        }
      }
      attribute.setMutability(sa.mutability());

      List<String> refType = Arrays.asList(sa.referenceTypes());

      // If we just have the default single empty string, set to null
      if (refType.isEmpty() || (refType.size() == 1 && refType.get(0).isEmpty())) {
        attribute.setReferenceTypes(null);
      } else {
        attribute.setReferenceTypes(Arrays.asList(sa.referenceTypes()));
      }

      attribute.setRequired(sa.required());
      attribute.setReturned(sa.returned());
      attribute.setUniqueness(sa.uniqueness());

      //if (sa.type().equals(Type.COMPLEX))
      ScimType st = f.getType().getAnnotation(ScimType.class);
      
      if (attribute.getType() == Type.COMPLEX || st != null) {
        Class<?> componentType;
        if (!attribute.isMultiValued()) {
          componentType = f.getType();
          attribute.setSubAttributes(createAttributes(urn, Arrays.asList(f.getType().getDeclaredFields()), invalidAttributes, nameBase + "." + f.getName()), AddAction.APPEND);
        } else if (f.getType().isArray()) {
          componentType = f.getType().getComponentType();
        } else {
          ParameterizedType stringListType = (ParameterizedType) f.getGenericType();
          componentType = (Class<?>) stringListType.getActualTypeArguments()[0];
        }
        
        List<Field> fl = ReflectionUtils.getFieldsUpTo(componentType, Object.class);
        List<Attribute> la = createAttributes(urn, fl, invalidAttributes, nameBase + "." + f.getName());
          
        attribute.setSubAttributes(la, AddAction.APPEND);
      }
      attributeList.add(attribute);
    }

    log.debug("Returning " + attributeList.size() + " attributes");
    return attributeList;
  }

  

  // private Provider<ScimGroup> groupProvider = null;
  // private Provider<ScimUser> userProvider = null;
}
