/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
import { expect } from 'chai'
import sinon from 'sinon'

import service from '../../../services/broadcast-channel/index'
import { MessageEvent } from '../../../services/broadcast-channel/message-event'
const { BroadcastChannel } = service.create('foo').instance

describe('BroadcastChannel', () => {
  it('is a function', () => {
    expect(BroadcastChannel).is.an('function')
  })

  it('has standard APIs', () => {
    const JamesBond = new BroadcastChannel('007')
    expect(JamesBond.name).is.an('string')
    expect(JamesBond.onmessage).is.an('null')
    expect(JamesBond.postMessage).is.an('function')
    expect(JamesBond.close).is.an('function')

    expect(JamesBond).to.have.ownProperty('name')
    expect(JamesBond).to.have.ownProperty('onmessage')
    expect(JamesBond).not.to.have.ownProperty('postMessage')
    expect(JamesBond).not.to.have.ownProperty('close')
    JamesBond.close()
  })

  it('name attribute is readonly', () => {
    const Wolverine = new BroadcastChannel('Logan')
    expect(Wolverine.name).to.equal('Logan')
    Wolverine.name = 'Wolverine'
    expect(Wolverine.name).to.equal('Logan')
    Wolverine.close()
  })

  describe('basci usage', () => {
    const Hulk = new BroadcastChannel('Avengers')
    const Stack = new BroadcastChannel('Avengers')
    const Steven = new BroadcastChannel('Avengers')
    const Logan = new BroadcastChannel('Mutants')
    const Erik = new BroadcastChannel('Mutants')

    beforeEach(() => {
      Hulk.onmessage = sinon.spy()
      Stack.onmessage = sinon.spy()
      Steven.onmessage = sinon.spy()
      Logan.onmessage = sinon.spy()
    })

    afterEach(() => {
      Hulk.onmessage = null
      Stack.onmessage = null
      Steven.onmessage = null
      Logan.onmessage = null
      Erik.onmessage = null
    })

    it('trigger onmessage', () => {
      Hulk.postMessage('Hulk Smash !!!')
      expect(Hulk.onmessage.callCount).to.be.equal(0)
      expect(Logan.onmessage.callCount).to.be.equal(0)
      expect(Stack.onmessage.callCount).to.be.equal(1)
      expect(Steven.onmessage.callCount).to.be.equal(1)
    })

    it('don\'t trigger onmessage itself', () => {
      Logan.postMessage('Any one here ?')
      expect(Hulk.onmessage.callCount).to.be.equal(0)
      expect(Logan.onmessage.callCount).to.be.equal(0)
      expect(Stack.onmessage.callCount).to.be.equal(0)
      expect(Steven.onmessage.callCount).to.be.equal(0)
    })

    it('send multi messages', () => {
      Hulk.postMessage('Hulk Smash !!!')
      Logan.postMessage('I will fight you !')
      Stack.postMessage('whatever')
      Hulk.postMessage('whatever')
      Stack.postMessage('whatever')
      Steven.postMessage('whatever')
      Stack.postMessage('whatever')

      expect(Hulk.onmessage.callCount).to.be.equal(4)
      expect(Logan.onmessage.callCount).to.be.equal(0)
      expect(Stack.onmessage.callCount).to.be.equal(3)
      expect(Steven.onmessage.callCount).to.be.equal(5)
    })

    it('send string message', () => {
      Stack.postMessage('I am Iron-Man.')

      expect(Hulk.onmessage.callCount).to.be.equal(1)
      expect(Steven.onmessage.callCount).to.be.equal(1)

      const event = Hulk.onmessage.firstCall.args[0]
      expect(event).is.an('object')
      expect(event.data).is.a('string')
      expect(event.data).to.be.equal('I am Iron-Man.')
    })

    it('send object message', () => {
      const message = {
        type: 'SOKOVIA ACCORDS',
        approvedCountry: 117,
        content: 'The Avengers shall no longer be a private organization.'
      }

      Stack.postMessage(message)

      const event = Steven.onmessage.firstCall.args[0]
      expect(event).is.an('object')
      expect(event.data).is.a('object')
      expect(event.data).to.deep.equal(message)
    })

    it('close channel', () => {
      Hulk.close()

      Steven.postMessage('come to fight !')
      expect(Hulk.onmessage.callCount).to.be.equal(0)
      expect(Stack.onmessage.callCount).to.be.equal(1)
      expect(Steven.onmessage.callCount).to.be.equal(0)
    })

    it('send message after close', () => {
      Hulk.close()

      expect(() => { Hulk.postMessage('I am leaving.') }).to.throw(Error)

      expect(Hulk.onmessage.callCount).to.be.equal(0)
      expect(Logan.onmessage.callCount).to.be.equal(0)
      expect(Stack.onmessage.callCount).to.be.equal(0)
      expect(Steven.onmessage.callCount).to.be.equal(0)
    })

    it('MessageEvent dafault parameters', () => {
      const event = new MessageEvent()

      expect(event).is.an('object')
      expect(event.data).to.be.null
      expect(event.type).to.be.equal('message')
      expect(event.origin).to.be.equal('')
      expect(event.target).to.be.null
      expect(event.source).to.be.null
      expect(event.timeStamp).to.be.a('number')
      expect(event.ports).to.be.an('array')
    })

    it('MessageEvent constructor', () => {
      const source = { type: 'empty' }
      const event = new MessageEvent('custom', {
        source,
        data: 'Nothing',
        origin: 'http://127.0.0.1',
        ports: ['8080']
      })

      expect(event).is.an('object')
      expect(event.data).to.be.equal('Nothing')
      expect(event.type).to.be.equal('custom')
      expect(event.origin).to.be.equal('http://127.0.0.1')
      expect(event.target).to.be.null
      expect(event.source).to.deep.equal(source)
      expect(event.timeStamp).to.be.a('number')
      expect(event.ports).to.deep.equal(['8080'])
    })

    it('use MessageEvent', () => {
      Steven.postMessage('Be Together.')

      const event = Stack.onmessage.firstCall.args[0]
      expect(event).is.an('object')
      expect(event.data).to.be.equal('Be Together.')
      expect(event.type).to.be.equal('message')
      expect(event.origin).to.be.equal('')
      expect(event.target).to.be.null
      expect(event.timeStamp).to.be.a('number')
    })

    it('invalid usage', () => {
      const stranger = {
        name: 'stranger',
        close: Erik.close,
        postMessage: Erik.postMessage
      }

      stranger.postMessage('hello world.')

      expect(Hulk.onmessage.callCount).to.be.equal(0)
      expect(Logan.onmessage.callCount).to.be.equal(0)
      expect(Stack.onmessage.callCount).to.be.equal(0)
      expect(Steven.onmessage.callCount).to.be.equal(0)

      stranger.close()
    })

    it('close all', () => {
      Hulk.close()
      Stack.close()
      Steven.close()
      Logan.close()
      Erik.close()

      // close again
      expect(() => {
        Hulk.close()
        Stack.close()
        Steven.close()
        Logan.close()
        Erik.close()
      }).to.not.throw
    })
  })
})
