/*
 * Copyright (C) 2022 Savoir-faire Linux Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation; either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public
 * License along with this program.  If not, see
 * <https://www.gnu.org/licenses/>.
 */
'use strict';

import dotenv from 'dotenv';
const node_env = process.env.NODE_ENV || 'development';
dotenv.config({ path: `.env.${node_env}` });

import cors from 'cors';
import express, { NextFunction, Request, Response } from 'express';
import session from 'express-session';
import { promises as fs } from 'fs';
import http from 'http';
import passport from 'passport';
import { IVerifyOptions, Strategy as LocalStrategy } from 'passport-local';
import path from 'path';
import { Server, Socket } from 'socket.io';
import { ExtendedError } from 'socket.io/dist/namespace';

import JamiDaemon from './JamiDaemon';
import Account from './model/Account';
import { Session } from './model/util';
//import { createRequire } from 'module';
//const require = createRequire(import.meta.url);
//const redis = require('redis-url').connect()
//const RedisStore = require('connect-redis')(session)
/*const passportSocketIo = require('passport.socketio')*/
import indexRouter from './routes/index.js';
import JamiRestApi from './routes/jami.js';
// import { sentrySetUp } from './sentry.js'

const configPath = 'jamiServerConfig.json';

//const sessionStore = new RedisStore({ client: redis })
const sessionStore = new session.MemoryStore();

interface User {
  id: string;
  config: UserConfig;
  username: string;
  accountFilter?: (account: any) => boolean;
}

interface UserConfig {
  accountId?: string;
  accounts: string;
  password?: string;
  username?: string;
  type?: string;
}

interface AppConfig {
  users: Record<string, UserConfig>;
  authMethods: unknown[];
}

const loadConfig = async (filePath: string): Promise<AppConfig> => {
  const config = { users: {}, authMethods: [] };
  try {
    return Object.assign(config, JSON.parse((await fs.readFile(filePath)).toString()));
  } catch (e) {
    console.log(e);
    return config;
  }
};

const saveConfig = (filePath: string, config: AppConfig) => {
  return fs.writeFile(filePath, JSON.stringify(config));
};

/*
Share sessions between Passport.js and Socket.io
*/

function logSuccess() {
  console.log('passportSocketIo authorized user with Success 😁');
}

function logFail() {
  console.log('passportSocketIo failed to authorized user 👺');
}

/*

tempAccounts holds users accounts while tempting to authenticate them on Jams.
connectedUsers  holds users accounts after they got authenticated by Jams.

Users should be removed from connectedUsers when receiving a disconnect
web socket call

*/
const tempAccounts: Record<
  string,
  {
    newUser: Express.User;
    done: (error: any, user?: any, options?: IVerifyOptions) => void;
  }
> = {};
const connectedUsers: Record<string, UserConfig> = {};

const createServer = async (appConfig: AppConfig) => {
  const app = express();
  console.log(`Loading server for ${node_env} with config:`);
  console.log(appConfig);

  const corsOptions = {
    origin: 'http://127.0.0.1:3000',
  };

  if (node_env === 'development') {
    const webpack = await import('webpack');
    const webpackDev = await import('webpack-dev-middleware');
    const webpackHot = await import('webpack-hot-middleware');
    const { default: webpackConfig } = await import('jami-web-client/webpack.config.js');

    const compiler = webpack.default(webpackConfig);
    app.use(
      webpackDev.default(compiler, {
        publicPath: webpackConfig.output?.publicPath,
      })
    );
    app.use(webpackHot.default(compiler));
  }

  /*
        Configuation for Passeport Js
    */
  app.disable('x-powered-by');

  const secret_key = process.env.SECRET_KEY_BASE;

  if (!secret_key) {
    throw new Error('SECRET_KEY_BASE undefined');
  }

  const sessionMiddleware = session({
    store: sessionStore,
    resave: false,
    saveUninitialized: true,
    cookie: {
      secure: false, //!development,
      maxAge: 2419200000,
    },
    secret: secret_key,
  });

  app.use(sessionMiddleware);
  app.use(passport.initialize());
  app.use(passport.session());
  // app.use(app.router)
  app.use(cors(corsOptions));

  const jami = new JamiDaemon((account: Account, conversation: any, message: any) => {
    console.log('JamiDaemon onMessage');

    if (conversation.listeners) {
      Object.values(conversation.listeners).forEach((listener: any) => {
        listener.socket.emit('newMessage', message);
      });
    }
  });
  const apiRouter = new JamiRestApi(jami).getRouter();

  /*
    io.use(passportSocketIo.authorize({
        key: 'connect.sid',
        secret: process.env.SECRET_KEY_BASE,
        store: sessionStore,
        passport: passport,
        cookieParser: cookieParser,
        //success: logSuccess(),
        // fail: logFail(),
    }))
    */

  const isSetupComplete = () => {
    return 'admin' in appConfig.users;
  };

  const accountFilter = (filter: string | string[]) => {
    if (typeof filter === 'string') {
      if (filter === '*') return undefined;
      else return (account: Account) => account.getId() === filter;
    } else if (Array.isArray(filter)) {
      return (account: Account) => filter.includes(account.getId());
    } else {
      throw new Error('Invalid account filter string');
    }
  };

  const user = (id: string, config: UserConfig) => {
    return {
      id,
      config,
      username: config.username || id,
      accountFilter: accountFilter(config.accounts),
    };
  };

  passport.serializeUser((user: any, done) => {
    user = user as User;
    connectedUsers[user.id] = user.config;
    console.log('=============================SerializeUser called ' + user.id);
    console.log(user);
    done(null, user.id);
  });

  const deserializeUser = (id: string, done: (err: any, user?: Express.User | false | null) => void) => {
    console.log('=============================DeserializeUser called on: ' + id);
    const userConfig = connectedUsers[id];
    console.log(userConfig);
    if (userConfig) {
      done(null, user(id, userConfig));
    } else done(404, null);
  };
  passport.deserializeUser(deserializeUser);

  const jamsStrategy = new LocalStrategy(async (username, password, done) => {
    const accountId = await jami.addAccount({
      managerUri: 'https://jams.savoirfairelinux.com',
      managerUsername: username,
      archivePassword: password,
    });
    const id = `jams_${username}`;
    const userConfig = { username, type: 'jams', accounts: accountId };
    const newUser = user(id, userConfig);
    console.log('AccountId: ' + accountId);
    tempAccounts[accountId] = { done, newUser };
  });
  jamsStrategy.name = 'jams';

  const localStrategy = new LocalStrategy((username, password, done) => {
    console.log('localStrategy: ' + username + ' ' + password);

    const id = username;
    const userConfig = appConfig.users[username];
    if (!userConfig) {
      return done(null, false, { message: 'Incorrect username.' });
    }
    if (userConfig.password !== password) {
      return done(null, false, { message: 'Incorrect password.' });
    }
    userConfig.type = 'local';

    done(null, user(id, userConfig));
  });

  passport.use(jamsStrategy);
  passport.use(localStrategy);

  const secured = (req: Request, res: Response, next: NextFunction) => {
    if (req.user) {
      return next();
    }
    res.status(401).end();
  };
  const securedRedirect = (req: Request, res: Response, next: NextFunction) => {
    const user = req.user as UserConfig | undefined;
    if (user?.accountId) {
      return next();
    }
    (req.session as any).returnTo = req.originalUrl;
    res.redirect('/login');
  };

  app.use(express.json());
  app.post('/setup', (req, res) => {
    if (isSetupComplete()) {
      return res.status(404).end();
    }
    if (!req.body.password) {
      return res.status(400).end();
    }
    console.log(req.body);
    appConfig.users.admin = {
      accounts: '*',
      password: req.body.password,
    };
    res.status(200).end();
    saveConfig(configPath, appConfig);
  });
  app.post('/auth/jams', passport.authenticate('jams'), (req, res) => {
    res.json({ loggedin: true });
  });
  app.post('/auth/local', passport.authenticate('local'), (req, res) => {
    res.json({ loggedin: true, user: (req.user as User | undefined)?.id });
  });

  const getState = (req: Request) => {
    if (req.user) {
      const user = req.user as UserConfig;
      return { loggedin: true, username: user.username, type: user.type };
    } else if (isSetupComplete()) {
      return {};
    } else {
      return { setupComplete: false };
    }
  };

  // sentrySetUp(app);

  app.get('/auth', (req, res) => {
    const state = getState(req);
    if (req.user) {
      res.json(state);
    } else {
      res.status(401).json(state);
    }
  });

  app.use('/api', secured, apiRouter);

  app.use('/', indexRouter);

  /* GET React App */

  const cwd = process.cwd();
  app.use(express.static(path.join(cwd, 'client/dist')));

  app.use((req, res) => {
    res.render(path.join(cwd, 'client/dist/index.ejs'), {
      initdata: JSON.stringify(getState(req)),
    });
  });

  // @ts-ignore TODO: Fix the typescript error
  const server = http.Server(app);

  const io = new Server(server, { cors: corsOptions });
  const wrap = (middleware: any) => (socket: Socket, next: (err?: ExtendedError) => void) =>
    middleware(socket.request, {}, next);
  io.use(wrap(sessionMiddleware));
  io.use(wrap(passport.initialize()));
  io.use(wrap(passport.session()));
  io.use((socket, next) => {
    if ((socket.request as any).user) {
      next();
    } else {
      next(new Error('unauthorized'));
    }
  });
  io.on('connect', (socket) => {
    console.log(`new connection ${socket.id}`);
    const session: Session = (socket.request as any).session;
    console.log(`saving sid ${socket.id} in session ${session.id}`);
    session.socketId = socket.id;
    session.save();

    socket.on('conversation', (data) => {
      console.log('io conversation');
      console.log(data);
      if (session.conversation) {
        console.log(`disconnect from old conversation ${session.conversation.conversationId}`);
        const conversation = jami.getConversation(session.conversation.accountId, session.conversation.conversationId);
        if (conversation) {
          delete conversation.listeners[socket.id];
        }
      }
      session.conversation = { accountId: data.accountId, conversationId: data.conversationId };
      const conversation = jami.getConversation(data.accountId, data.conversationId);
      if (conversation) {
        if (!conversation.listeners) {
          conversation.listeners = {};
        }
        conversation.listeners[socket.id] = {
          socket,
          session,
        };
      }
      session.save();
    });
  });

  return server;
};

loadConfig(configPath)
  .then(createServer)
  .then((server) => {
    server.listen(3000);
  });
