/**
 * @jest-environment node
 */

import { createLogger } from '../utils/logger'
import SdkApi, { Context } from '../api'
import * as EnhancedContentApi from '../enhancedContent'

jest.mock('../utils/logger')
let context: Context | undefined
;(createLogger as jest.Mock).mockImplementation(function (ctx: Context) {
  context = ctx
  return { log: jest.fn() }
})

const defaultOptions = {
  clientId: 'client-id',
}

describe('SdkApi', () => {
  let sdk: SdkApi

  beforeEach(() => {
    sdk = new SdkApi('npm')
  })

  test('constructed uninitialized', () => {
    expect(sdk.initialized).toBe(false)
    expect(context).toBeUndefined()

    const accessEc = (): EnhancedContentApi.default => sdk.enhancedContent
    expect(accessEc).toThrow('Salsify Experiences SDK has not been initialized.')
  })

  test('can only be initialized once', () => {
    sdk.init(defaultOptions)

    const reinit = (): void => sdk.init(defaultOptions)
    expect(reinit).toThrow('Salsify Experiences SDK has already been initialized.')
  })

  test('allows API access once initialized', () => {
    sdk.init(defaultOptions)
    expect(sdk.enhancedContent).toBeTruthy()
  })

  test('allow events API access once initialized', () => {
    sdk.init(defaultOptions)
    expect(sdk.events).toBeTruthy()
  })

  test('session ID is not set when running on a server', () => {
    sdk.init(defaultOptions)
    expect(context).toMatchObject({ sessionId: undefined })
  })

  test('iframe context listener is not attached', () => {
    const attachIframeContextListenerSpy = jest.spyOn(EnhancedContentApi, 'attachIframeContextListener')

    sdk.init({ ...defaultOptions })

    expect(attachIframeContextListenerSpy).not.toHaveBeenCalled()
  })
})
