/*
 * Jooby https://jooby.io
 * Apache License Version 2.0 https://jooby.io/LICENSE.txt
 * Copyright 2014 Edgar Espina
 */
package io.jooby.internal.openapi;

import java.io.File;
import java.nio.file.Path;
import java.util.Iterator;
import java.util.Set;

import com.fasterxml.jackson.databind.ObjectMapper;
import io.jooby.*;
import io.swagger.v3.core.converter.AnnotatedType;
import io.swagger.v3.core.converter.ModelConverter;
import io.swagger.v3.core.converter.ModelConverterContext;
import io.swagger.v3.core.jackson.AbstractModelConverter;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.FileSchema;
import io.swagger.v3.oas.models.media.Schema;

public class ModelConverterExt extends AbstractModelConverter {

  private static final Set<String> IGNORE =
      Set.of(
          Jooby.class.getName(),
          "io.jooby.kt.Kooby",
          ServiceRegistry.class.getName(),
          Router.class.getName());

  public ModelConverterExt(ObjectMapper mapper) {
    super(mapper);
  }

  @Override
  public Schema resolve(
      AnnotatedType type, ModelConverterContext context, Iterator<ModelConverter> chain) {
    var javaType = _mapper.getTypeFactory().constructType(type.getType());
    if (javaType.isCollectionLikeType() || javaType.isArrayType()) {
      if (isFile(javaType.getContentType().getRawClass())) {
        return new ArraySchema().items(new FileSchema());
      }
    }
    if (isFile(javaType.getRawClass())) {
      return new FileSchema();
    }
    // Skip base apps
    if (IGNORE.contains(javaType.getRawClass().getName())) {
      return null;
    }
    return super.resolve(type, context, chain);
  }

  private boolean isFile(Class<?> type) {
    return type == FileUpload.class || type == Path.class || type == File.class;
  }
}
