import { EventEmitter } from 'events';

const { createScreen } = process._linkedBinding('electron_browser_screen');

let _screen: Electron.Screen;

const createScreenIfNeeded = () => {
  if (_screen === undefined) {
    _screen = createScreen();
  }
};

// We can't call createScreen until after app.on('ready'), but this module
// exposes an instance created by createScreen. In order to avoid
// side-effecting and calling createScreen upon import of this module, instead
// we export a proxy which lazily calls createScreen on first access.
export default new Proxy(
  {},
  {
    get: (target, property: keyof Electron.Screen) => {
      createScreenIfNeeded();
      const value = _screen[property];
      if (typeof value === 'function') {
        return value.bind(_screen);
      }
      return value;
    },
    set: (target, property: string, value: unknown) => {
      createScreenIfNeeded();
      return Reflect.set(_screen, property, value);
    },
    ownKeys: () => {
      createScreenIfNeeded();
      return Reflect.ownKeys(_screen);
    },
    has: (target, property: string) => {
      createScreenIfNeeded();
      return property in _screen;
    },
    getOwnPropertyDescriptor: (target, property: string) => {
      createScreenIfNeeded();
      return Reflect.getOwnPropertyDescriptor(_screen, property);
    },
    getPrototypeOf: () => {
      // This is necessary as a result of weirdness with EventEmitterMixin
      // and FunctionTemplate - we need to explicitly ensure it's returned
      // in the prototype.
      return EventEmitter.prototype;
    }
  }
);
