import { createServer } from 'http';
import { execute, subscribe } from 'graphql';
import { graphqlExpress, graphiqlExpress } from 'graphql-server-express';
import { SubscriptionServer } from 'subscriptions-transport-ws';
import bodyParser from 'body-parser';
import express from 'express';
import jwt from 'jsonwebtoken';
import fs from 'fs';

import schema from './schema';
import loaders from './Loaders';

const app = express();
const PORT = 3000;
const cert = process.env.NODE_ENV === 'dev'
  ? 'hive'
  : fs.readFileSync('/etc/letsencrypt/production/certs/madbean.ovh/fullchain.pem');

app.use(bodyParser.json());

const error = res => res.status(403).json({ error: 'No credentials sent!' });

app.use((req, res, next) => {
  const bearer = req.headers.authorization;
  const token = bearer.replace('Bearer ', '');
  jwt.verify(token, cert, { algorithms: ['RS256'] }, (err, { data }) => {
    if (data && data.userID && data.userID !== '') {
      next();
    } else {
      error(res);
    }
  });
});

app.use('/graphql', graphqlExpress({
  context: {
    loaders,
  },
  schema,
  tracing: true,
  cacheControl: true,
}));

app.use('/graphiql', graphiqlExpress({
  endpointURL: '/graphql',
  subscriptionsEndpoint: `ws://localhost:${PORT}/subscriptions`,
}));

const server = createServer(app);

server.listen(PORT, () => {
  new SubscriptionServer({
    execute,
    subscribe,
    schema,
    onConnect: () => console.log('new client connected'),
  }, {
    server,
    path: '/subscriptions',
  });
});

console.log(`Middle running at http://localhost:${PORT}`);
