import { injectable } from 'inversify';
import { isDev } from '../../core/env';
import { ISessionHelper } from './i-session-helper';

const defaultCsp: IContentSecurityPolicy = {
  'default-src': ["'self'"],
  'style-src': ["'unsafe-inline'"],
  'object-src': ["'none'"],
};

@injectable()
export class SessionHelper implements ISessionHelper {
  private static stringifyCspHeader(csp: IContentSecurityPolicy): string {
    return Object.entries(csp)
      .map((directive: [string, CspValue[]]) => `${directive[0]} ${directive[1]?.join(' ')}`)
      .join('; ');
  }

  public setCsp(window: Electron.BrowserWindow, csp: IContentSecurityPolicy): void {
    const mergedCsp: IContentSecurityPolicy = { ...defaultCsp, ...csp };

    if (isDev()) {
      mergedCsp['default-src'] = ['devtools:'].concat(mergedCsp['default-src'] ?? []);
      mergedCsp['script-src'] = ["'unsafe-eval'"].concat(mergedCsp['script-src'] ?? []);
      mergedCsp['script-src-elem'] = ['file:', 'devtools:', "'unsafe-inline'"].concat(
        mergedCsp['script-src-elem'] ?? []
      );
      mergedCsp['style-src'] = ['devtools:', "'unsafe-inline'"].concat(mergedCsp['style-src'] ?? []);
      mergedCsp['img-src'] = ['devtools:'].concat(mergedCsp['img-src'] ?? []);
      mergedCsp['connect-src'] = ['devtools:', 'data:'].concat(mergedCsp['connect-src'] ?? []);
      mergedCsp['worker-src'] = ['devtools:'].concat(mergedCsp['worker-src'] ?? []);
    }

    window.webContents.session.webRequest.onHeadersReceived((details, callback) => {
      callback({
        responseHeaders: {
          ...details.responseHeaders,
          'Content-Security-Policy': SessionHelper.stringifyCspHeader(mergedCsp),
        },
      });
    });
  }
}
