import mongoose from "mongoose";
import EventStoreRabbit from "./_infra/EventStoreRabbit";
import ScreenshotRepositoryMongoAndFile from "./_infra/ScreenshotRepositoryMongoAndFile";
import SessionRepositoryMongo from "./_infra/SessionRepositoryMongo";
import WebSiteRepositoryMongoREST from "./_infra/WebSiteRepositoryREST";
import RESTServer from "./_ui/RESTServer";
import SessionService from "./application/SessionService";
import config from "./_infra/config";
import VideoRepositoryMongoAndFile from "./_infra/VideoRepositoryMongoAndFile";

import * as winston from "winston";
const logger = winston.createLogger({
    level: 'info',
    format: winston.format.combine(
      winston.format.label({ label: '[Session]' }),
      winston.format.timestamp({
        format: 'YYYY-MM-DD HH:mm:ss'
      }),
      //
      // The simple format outputs
      // `${level}: ${message} ${[Object with everything else]}`
      //
      //winston.format.simple()
      //
      // Alternatively you could use this custom printf format if you
      // want to control where the timestamp comes in your final message.
      // Try replacing `format.simple()` above with this:
      //
      winston.format.printf(info => `${info.label} - ${info.level} - ${info.message} (${info.timestamp})`)
    ),
    transports: [
      //
      // - Write all logs with level `error` and below to `error.log`
      // - Write all logs with level `info` and below to `combined.log`
      //
      new winston.transports.Console(),
      new winston.transports.File({ filename: 'error.log', level: 'error' }),
      new winston.transports.File({ filename: 'combined.log' }),
    ],
  });
  
  //
  // If we're not in production then log to the `console` with the format:
  // `${info.level}: ${info.message} JSON.stringify({ ...rest }) `
  //
  if (process.env.NODE_ENV === 'production') {
    // logger.add(new winston.transports.Console({
    //   format: winston.format.simple()
    // }));
  }
// Init database
connectWithRetry();

const webSiteRepository = new WebSiteRepositoryMongoREST();
const sessionRespository = new SessionRepositoryMongo(webSiteRepository);
const eventStore = new EventStoreRabbit();
const screenshotRepository = new ScreenshotRepositoryMongoAndFile();
const videoRepository = new VideoRepositoryMongoAndFile();

const sessionService = new SessionService(sessionRespository, webSiteRepository, eventStore, screenshotRepository, videoRepository, logger);

function connectWithRetry(): Promise<void> {
    return mongoose.connect(config.database, { useUnifiedTopology: true, useNewUrlParser: true })
        .then(() => {
            logger.info("Connecting to database : " + config.database );
        });
}

// Create RESTServer
const httpServer = new RESTServer(config.port, sessionService, logger);

httpServer.start();
