import {
  createLoggerFromContext,
  Logger,
  LoggerMetaData
} from "../lib/index";

export const createMockLogger = <T>(): Logger<T> => {
  const logger: Logger<T> = {
    debug: jest.fn(),
    info: jest.fn(),
    warn: jest.fn(),
    error: jest.fn(),
    profile: jest.fn(),
    extend: jest.fn()
  };
  return logger;
};

const loggerMock = createMockLogger();

const creator = (meta: LoggerMetaData, level: string): Logger<{}> => {
  return loggerMock;
}

export type Event =
  | Invoked
  | InvalidParams;

export enum EventType {
  Invoked = "messages/get/INVOKED",
  InvalidParams = "messages/get/INVALID_PARAMS"
}

export interface Invoked {
  type: EventType.Invoked;
}

export interface InvalidParams {
  type: EventType.InvalidParams;
}


const createLogger = createLoggerFromContext("APP", "Stage", "debug", creator);
const logger: Logger<Event> = createLogger("requestId");

describe("logger", () => {
  it('debug is called on the loggerMock', () => {
    logger.debug({ type: EventType.Invoked });
    expect(loggerMock.debug).toBeCalledWith({ type: EventType.Invoked });
  });

  it('info is called on the loggerMock', () => {
    logger.info({ type: EventType.Invoked });
    expect(loggerMock.info).toBeCalledWith({ type: EventType.Invoked });
  });

  it('warning is called on the loggerMock', () => {
    logger.warn({ type: EventType.Invoked });
    expect(loggerMock.warn).toBeCalledWith({ type: EventType.Invoked });
  });

  it('error is called on the loggerMock', () => {
    logger.error({ type: EventType.InvalidParams });
    expect(loggerMock.error).toBeCalledWith({ type: EventType.InvalidParams });
  });

  it('profile is called on the loggerMock', () => {
    logger.profile("profile id");
    expect(loggerMock.profile).toBeCalledWith("profile id");
  });

  it('extend is called on the loggerMock to add to current context', () => {
    logger.extend({ id: 'abc' });
    expect(loggerMock.extend).toBeCalledWith({ id: 'abc' });
  });
});
