//  tslint:disable: object-literal-sort-keys no-empty only-arrow-functions
import * as internal from '../../gulpfile.ts/internal'
import { TIMPLA_DEFAULTS } from '../../gulpfile.ts/lib/TIMPLA_DEFAULTS'
import { webpackMultiConfig } from '../../gulpfile.ts/lib/webpackMultiConfig'
import { clone } from '../helpers'

jest.mock('../../gulpfile.ts/internal')
jest.mock('path')

const spyLazyImport: any = jest.spyOn(internal, 'lazyImport')
const spySureLazyImport: any = jest.spyOn(internal, 'sureLazyImport')
const spyGetFirstValidObject = jest.spyOn(internal, 'getFirstValidObject')

const mockConstructs: any = {
  'terser-webpack-plugin': function TerserWebpackPlugin() {},
  'hard-source-webpack-plugin': function HardSourceWebpackPlugin() {},
  'fork-ts-checker-webpack-plugin': function ForkTsCheckerWebpackPlugin() {},
  'speed-measure-webpack-plugin': function SpeedMeasureWebpackPlugin() {
    return {
      wrap: jest.fn().mockImplementation(a => ({
        ...a,
        isSMPWrapped: true,
      })),
    }
  },
  'webpack-bundle-analyzer': {
    BundleAnalyzerPlugin: function BundleAnalyzerPlugin() {},
  },
  './tsUtils': {
    tsWbformatter: jest.fn(),
  },
}

const getMockConstruct = (name: string) => {
  return mockConstructs[name]
}

const originalTP = { ...internal.TIMPLA_PROCESS }

spyLazyImport.mockImplementation(getMockConstruct)
spySureLazyImport.mockImplementation(getMockConstruct)
spyGetFirstValidObject.mockReturnValue({})

beforeEach(() => {
  // Restore TP as it may have been changed
  Object.entries(originalTP).forEach(([a, b]) => {
    ;(internal.TIMPLA_PROCESS as any)[a] = b
  })
})

describe('webpackMultiConfig', () => {
  it('should return a valid default config when no options are supplied', () => {
    const hocConfig = webpackMultiConfig(TIMPLA_DEFAULTS)
    const result = hocConfig('development')
    expect(result).toMatchSnapshot()
  })
  it('should disable eslint when development.eslint is set to false', () => {
    const conf = clone(TIMPLA_DEFAULTS)
    conf.development.eslint = false
    const hocConfig = webpackMultiConfig(conf)
    const result = hocConfig('development')
    expect(result).toMatchSnapshot()
  })
  it('should disable tslint when development.tslint is set to false', () => {
    const conf = clone(TIMPLA_DEFAULTS)
    conf.development.tslint = false
    const hocConfig = webpackMultiConfig(conf)
    const result = hocConfig('development')
    expect(result).toMatchSnapshot()
  })
  it('should disable hmr when development.webpackHotMiddlewareClient is set to false', () => {
    const conf = clone(TIMPLA_DEFAULTS)
    conf.development.webpackHotMiddlewareClient = false
    const hocConfig = webpackMultiConfig(conf)
    const result = hocConfig('development')
    expect(result).toMatchSnapshot()
  })
  it('should disable webpackBundleAnalyzer when javascripts.webpackBundleAnalyzerOptions is set to false', () => {
    const conf = clone(TIMPLA_DEFAULTS)
    conf.javascripts.webpackBundleAnalyzerOptions = false
    const hocConfig = webpackMultiConfig(conf)
    const result = hocConfig('development')
    expect(result).toMatchSnapshot()
  })
  it('should return a production config', () => {
    const conf = clone(TIMPLA_DEFAULTS)
    const hocConfig = webpackMultiConfig(conf)
    const result = hocConfig('production')
    expect(result).toMatchSnapshot()
  })
  it('should use the speedMeasurePlugin when TP.MEASURE is set to true', () => {
    const conf = clone(TIMPLA_DEFAULTS)
    const hocConfig = webpackMultiConfig(conf)
    internal.TIMPLA_PROCESS.MEASURE = true
    const result = hocConfig('production')
    expect(result.isSMPWrapped).toBeTruthy()
  })
})
