import 'dart:io';
import 'dart:async';

import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart';
import 'package:shelf_router/shelf_router.dart';
import 'package:shelf_static/shelf_static.dart';

import 'database/database_provider.dart';
import 'routes/auth_routes.dart';
import 'routes/geo_routes.dart';

Middleware _corsMiddleware = (Handler innerHandler) {
  return (Request request) {
    final headers = <String, String>{
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
      'Access-Control-Allow-Headers': 'Content-Type, Authorization',
      'Access-Control-Max-Age': '86400',
    };

    if (request.method == 'OPTIONS') {
      return Response.ok(null, headers: headers);
    }

    return Future.value(innerHandler(request)).then((response) => response.change(headers: headers));
  };
};

void main(List<String> args) async {
  final database = DatabaseProvider();
  await database.initialize();

  Timer.periodic(const Duration(minutes: 5), (timer) {
    database.cleanupExpired();
  });

  final authRoutes = AuthRoutes(database);
  final geoRoutes = GeoRoutes(database);

 final router = Router()
    ..mount('/', authRoutes.routes.call)
    ..mount('/', geoRoutes.routes.call);

  final staticHandler = createStaticHandler('web', defaultDocument: 'index.html');
  final apiHandler  = createStaticHandler('web/swagger', defaultDocument: 'index.html');

  final handler = Pipeline()
      .addMiddleware(_corsMiddleware)
      .addMiddleware(logRequests())
      .addHandler(Cascade()
          .add(apiHandler)
          .add(staticHandler)
          .add(router.call)
          .handler);

  final ip = InternetAddress.anyIPv4;
  final port = int.parse(Platform.environment['PORT'] ?? '9090');
  final server = await serve(handler, ip, port);
  print('Server listening on port ${server.port}');
}