import NIOSSL
import Fluent
import FluentPostgresDriver
import Vapor
import Foundation

// configures your application
public func configure(_ app: Application) async throws {
    // uncomment to serve files from /Public folder
    app.middleware.use(CORSMiddleware())
    let corsConfiguration = CORSMiddleware.Configuration(
        allowedOrigin: .all,
        allowedMethods: [.GET, .POST, .PUT, .OPTIONS, .DELETE, .PATCH],
        allowedHeaders: [.accept, .authorization, .contentType, .origin, .xRequestedWith, .userAgent, .accessControlAllowOrigin]
    )
    let cors = CORSMiddleware(configuration: corsConfiguration)
    // cors middleware should come before default error middleware using `at: .beginning`
    app.middleware.use(cors, at: .beginning)
    
    app.http.server.configuration.port = 3003
    
    app.databases.use(DatabaseConfigurationFactory.postgres(configuration: .init(
        hostname: Environment.get("DATABASE_HOST") ?? "localhost",
        port: Environment.get("DATABASE_PORT").flatMap(Int.init(_:)) ?? SQLPostgresConfiguration.ianaPortNumber,
        username: Environment.get("DATABASE_USERNAME") ?? "mcarman",
        password: Environment.get("DATABASE_PASSWORD") ?? "@ng31F@rm0823262",
        database: Environment.get("DATABASE_NAME") ?? "cm",
        tls: .disable)
    ), as: .psql)
    
    let timeout = HTTPClient.Configuration.Timeout(connect: .seconds(300), read: .seconds(300) )
    app.http.client.configuration.timeout = timeout

    app.migrations.add(mdlCategory.Create())
    app.migrations.add(mdlComparisonType.Create())
    app.migrations.add(mdlComparisonType.Seed())
    app.migrations.add(mdlCompartment.Create())
    app.migrations.add(mdlCompartmentLocation.Create())
    app.migrations.add(mdlDataType.Create())
    app.migrations.add(mdlDataType.Seed())
    app.migrations.add(mdlUnit.Create())
    app.migrations.add(mdlValueType.Create())
    app.migrations.add(mdlValueType.Seed())
    app.migrations.add(mdlInputType.Create())
    app.migrations.add(mdlInputType.Seed())
    app.migrations.add(mdlJobSite.Create())
    app.migrations.add(mdlJobSite.Seed())
    app.migrations.add(mdlPriority.Create())
    app.migrations.add(mdlPriority.Seed())
    app.migrations.add(mdlRepairType.Create())
    app.migrations.add(mdlRepairType.Seed())
    app.migrations.add(mdlRole.Create())
    app.migrations.add(mdlRole.Seed())
    app.migrations.add(mdlState.Create())
    app.migrations.add(mdlState.Seed())
    app.migrations.add(mdlStatus.Create())
    app.migrations.add(mdlStatus.Seed())
    app.migrations.add(mdlDivision.Create())
    app.migrations.add(mdlLabSetting.Create())
    app.migrations.add(mdlLocation.Create())
    app.migrations.add(mdlFluid.Create())
    app.migrations.add(mdlFuel.Create())
    app.migrations.add(mdlIncompleteReason.Create())
    app.migrations.add(mdlLevel.Create())
    app.migrations.add(mdlNoteType.Create())
    app.migrations.add(mdlPart.Create())
    app.migrations.add(mdlSignatureType.Create())
    app.migrations.add(mdlReason.Create())
    app.migrations.add(mdlViscosity.Create())
    app.migrations.add(mdlGate.Create())
    app.migrations.add(mdlCustomer.Create())
    app.migrations.add(mdlContactType.Create())
    app.migrations.add(mdlContactType.Seed())
    app.migrations.add(mdlContact.Create())
    app.migrations.add(mdlContactInfo.Create())
    app.migrations.add(mdlContact.makeParentCustomer())
    app.migrations.add(mdlResponseType.Create())
    app.migrations.add(mdlSMSCCode.Create())
    app.migrations.add(mdlUser.Create())
    app.migrations.add(mdlXUserRole.Create())
    app.migrations.add(mdlXFluidViscosity.Create())
    app.migrations.add(mdlEquipmentType.Create())
    app.migrations.add(mdlEquipmentType.Seed())
    app.migrations.add(mdlProduct.Create())
    app.migrations.add(mdlMake.Create())
    app.migrations.add(mdlModel.Create())
    app.migrations.add(mdlEquipment.Create())
    app.migrations.add(mdlObjProperty.Create())
    app.migrations.add(mdlEquipment.AddParent())
    app.migrations.add(mdlItem.Create())
    app.migrations.add(mdlItemResponseType.Create())
    app.migrations.add(mdlSpec.Create())
    app.migrations.add(mdlSpecItem.Create())
    app.migrations.add(mdlSpecItemValue.Create())
    app.migrations.add(mdlWorkOrder.Create())
    app.migrations.add(mdlSegment.Create())
    app.migrations.add(mdlSegment.Seed())
    app.migrations.add(mdlOilSample.Create())
    app.migrations.add(mdlXWorkOrderSegment.Create())
    app.migrations.add(mdlXUserRole.FixRoleId())
    app.migrations.add(mdlSpecItemValue.Mod1())
    app.migrations.add(mdlSpecItemValue.Mod2())
    app.migrations.add(mdlOilSample.Mod1())
    app.migrations.add(mdlXFluidViscosity.Mod1())
    app.migrations.add(mdlContact.Mod1())
    app.migrations.add(mdlResponseType.Mod1())
    app.migrations.add(mdlLabSetting.Mod1())
    app.migrations.add(mdlLabSetting.Mod2())
    app.migrations.add(mdlLocation.Mod1())
    app.migrations.add(mdlWorkOrderAttachment.Create())
    app.migrations.add(mdlWorkOrderFlow.Create())
    app.migrations.add(mdlWorkOrder.Mod1())
    app.migrations.add(mdlWorkOrderPart.Create())
    app.migrations.add(mdlWorkOrderPart.Mod1())
    app.migrations.add(mdlSignatureType.Mod1())
    app.migrations.add(mdlSignature.Create())
    app.migrations.add(mdlInspectionType.Create())
    app.migrations.add(mdlInspectionLevel.Create())
    app.migrations.add(mdlWorkOrderSegment.Create())
    app.migrations.add(mdlWorkOrderPart.Mod2())
    app.migrations.add(mdlXWorkOrderSegment.Delete())
    app.migrations.add(mdlInspection.Create())
    app.migrations.add(mdlInspectionCategory.Create())
    app.migrations.add(mdlInspectionItem.Create())
    app.migrations.add(mdlInspectionItemResponse.Create())
    app.migrations.add(mdlInspectionItem.Mod1())
    app.migrations.add(mdlInspectionItem.Mod2())
    app.migrations.add(mdlInspectionItemSpec.Create())
    app.migrations.add(mdlInspectionItemSpecItem.Create())
    app.migrations.add(mdlInspectionItemSpecItemTest.Create())
    app.migrations.add(mdlInspectionItemSpecItemValue.Create())
    app.migrations.add(mdlNote.Create())
    app.migrations.add(mdlNote.Mod1())
    app.migrations.add(mdlOilSample.Mod2())
    app.migrations.add(mdlConsumption.Create())
    app.migrations.add(mdlConsumption.Mod1())
    app.migrations.add(mdlTemplate.Create())
    app.migrations.add(mdlTemplate.Mod1())
    app.migrations.add(mdlTemplateCategory.Create())
    app.migrations.add(mdlTemplateItemSpec.Create())
    app.migrations.add(Token.Create())
    app.migrations.add(mdlLicense.Create())
    
    app.logger.logLevel = .debug
    
    try await app.autoMigrate()

    // register routes
    try routes(app)
}


