describe "SyncViewer", ->

  beforeEach ->
    this.fixtures = fixture.load("syncViewer.html",  "user_sync_track1.json"); # append these fixtures which were already cached
    this.server = sinon.fakeServer.create();
    window.jamClient = sinon.stub()
    this.syncViewer = new JK.SyncViewer()
    this.syncViewer.init()
    $('body').append(this.syncViewer.root)
    this.track1 = this.fixtures[1]["entries"][0]
    window.gon = {}
    window.gon.isNativeClient = true

    callback = sinon.spy()
    window.jamClient.GetLocalRecordingState = sinon.stub().returns({recordings: []})
    window.jamClient.GetRecordingManagerState = sinon.stub().returns({running: false})
    window.jamClient.IsNativeClient = sinon.stub().returns(true)


  afterEach ->
    this.server.restore();

  it "display state correctly", ->
    $track = this.syncViewer.createTrack(this.track1)
    this.syncViewer.updateTrackState($track)

    expect($track.find('.client-state .msg')).toContainText('MISSING')
    expect($track.find('.upload-state .msg')).toContainText('PENDING UPLOAD')

    this.track1.fully_uploaded = true

    this.syncViewer.updateTrackState($track)

    expect($track.find('.upload-state .msg')).toContainText('UPLOADED')


  describe "no track", ->

    beforeEach ->
      this.syncViewer.load()

      this.server.requests[0].respond(
        200,
        { "Content-Type": "application/json" },
        JSON.stringify({ next: null, entries: []})
      );


    it "loads empty", ->

      expect(this.syncViewer.list.find('.no-syncs')).toExist();


  describe "one track", ->
    beforeEach ->
      this.syncViewer.load()

      this.server.requests[0].respond(
        200,
        { "Content-Type": "application/json" },
        JSON.stringify({ next: null, entries: [this.track1]})
      );


    it "loads single track", ->

      expect(this.syncViewer.list.find('.no-syncs')).not.toExist();
      $track = this.syncViewer.list.find('.recorded-track')
      expect($track).toHaveLength(1);
      expect($track.find('.client-state .msg')).toContainText('MISSING')
      expect($track.find('.upload-state .msg')).toContainText('PENDING UPLOAD')

    it "handles recorded_track upload progress events correctly", ->

      commandMetadata = {queue: 'upload', type: 'recorded_track', action: 'upload', recording_id: this.track1.recording_id, track_id: this.track1.client_track_id}
      cmd = {commandId: '1', commandType: 'upload', commandMetadata: commandMetadata }

      # first we should see that recording manager is paused
      expect(this.syncViewer.downloadProgress).toHaveClass('paused')
      expect(this.syncViewer.uploadProgress).toHaveClass('paused')

      # send in a start command
      this.syncViewer.fileManagerCmdStart(null, cmd)

      expect(this.syncViewer.downloadProgress).toHaveClass('paused')
      expect(this.syncViewer.uploadProgress).toHaveClass('busy')

      $recordedTrackProgress = this.syncViewer.uploadProgress.find('.recorded-track.sync')
      expect($recordedTrackProgress).toHaveLength(1)
      expect($recordedTrackProgress.find('.progress')).toBeHidden()

      cmd.percentage = 50 # half way done
      this.syncViewer.fileManagerCmdProgress(null, cmd)

      expect($recordedTrackProgress.find('.progress')).toBeVisible()

      # command is over; progress element should be removed now
      this.syncViewer.fileManagerCmdStop(null, cmd)

      expect(this.syncViewer.downloadProgress).toHaveClass('paused')
      expect(this.syncViewer.uploadProgress).toHaveClass('paused')
      expect($recordedTrackProgress).not.toBeInDOM() # got removed

    it "handles mix download progress events correctly", ->

      commandMetadata = {queue: 'download', type: 'mix', action: 'download'}
      cmd = {commandId: '1', commandType: 'download', commandMetadata: commandMetadata }

      # first we should see that recording manager is paused
      expect(this.syncViewer.downloadProgress).toHaveClass('paused')
      expect(this.syncViewer.uploadProgress).toHaveClass('paused')

      # send in a start command
      this.syncViewer.fileManagerCmdStart(null, cmd)

      expect(this.syncViewer.downloadProgress).toHaveClass('busy')
      expect(this.syncViewer.uploadProgress).toHaveClass('paused')

      $progress = this.syncViewer.downloadProgress.find('.generic.sync')
      expect($progress).toHaveLength(1)
      expect($progress.find('span.text')).toHaveText('DOWNLOADING MIX')

      cmd.percentage = 50 # half way done
      this.syncViewer.fileManagerCmdProgress(null, cmd)

      # nothing happens in percentage update

      # command is over; progress element should be removed now
      this.syncViewer.fileManagerCmdStop(null, cmd)

      expect(this.syncViewer.downloadProgress).toHaveClass('paused')
      expect(this.syncViewer.uploadProgress).toHaveClass('paused')
      expect($progress).not.toBeInDOM() # got removed

    it "handles recorded track convert progress events correctly", ->

      commandMetadata = {queue: 'upload', type: 'recorded_track', action: 'convert'}
      cmd = {commandId: '1', commandType: 'upload', commandMetadata: commandMetadata }

      # first we should see that recording manager is paused
      expect(this.syncViewer.downloadProgress).toHaveClass('paused')
      expect(this.syncViewer.uploadProgress).toHaveClass('paused')

      # send in a start command
      this.syncViewer.fileManagerCmdStart(null, cmd)

      expect(this.syncViewer.uploadProgress).toHaveClass('busy')
      expect(this.syncViewer.downloadProgress).toHaveClass('paused')

      $progress = this.syncViewer.uploadProgress.find('.generic.sync')
      expect($progress).toHaveLength(1)
      expect($progress.find('span.text')).toHaveText('COMPRESSING TRACK')

      cmd.percentage = 50 # half way done
      this.syncViewer.fileManagerCmdProgress(null, cmd)

      # nothing happens in percentage update

      # command is over; progress element should be removed now
      this.syncViewer.fileManagerCmdStop(null, cmd)

      expect(this.syncViewer.downloadProgress).toHaveClass('paused')
      expect(this.syncViewer.uploadProgress).toHaveClass('paused')
      expect($progress).not.toBeInDOM() # got removed

    it "handles stream mix upload progress events correctly", ->

      commandMetadata = {queue: 'upload', type: 'stream_mix', action: 'upload'}
      cmd = {commandId: '1', commandType: 'upload', commandMetadata: commandMetadata }

      # first we should see that recording manager is paused
      expect(this.syncViewer.downloadProgress).toHaveClass('paused')
      expect(this.syncViewer.uploadProgress).toHaveClass('paused')

      # send in a start command
      this.syncViewer.fileManagerCmdStart(null, cmd)

      expect(this.syncViewer.uploadProgress).toHaveClass('busy')
      expect(this.syncViewer.downloadProgress).toHaveClass('paused')

      $progress = this.syncViewer.uploadProgress.find('.generic.sync')
      expect($progress).toHaveLength(1)
      expect($progress.find('span.text')).toHaveText('UPLOADING STREAM MIX')

      cmd.percentage = 50 # half way done
      this.syncViewer.fileManagerCmdProgress(null, cmd)

      # nothing happens in percentage update

      # command is over; progress element should be removed now
      this.syncViewer.fileManagerCmdStop(null, cmd)

      expect(this.syncViewer.downloadProgress).toHaveClass('paused')
      expect(this.syncViewer.uploadProgress).toHaveClass('paused')
      expect($progress).not.toBeInDOM() # got removed






    it "displays hover info over recorded-track", ->

      $track = this.syncViewer.list.find('.recorded-track')

      # should show over client state
      $clientState = $track.find('.client-state')
      expect($clientState).toHaveLength(1);
      $clientState.btOn()
      $hoverHelp = $('.help-hover-recorded-tracks')
      expect($hoverHelp).toHaveLength(1);

      # also verify that the message is correct about client state and upload state
      expect($hoverHelp.find('.client-state .msg')).toContainText('MISSING')
      expect($hoverHelp.find('.upload-state .msg')).toContainText('PENDING UPLOAD')

      $clientState.btOff()

      # as well as show over upload state
      $uploadState = $track.find('.upload-state')
      expect($uploadState).toHaveLength(1);
      $uploadState.btOn()
      $hoverHelp = $('.help-hover-recorded-tracks')
      expect($hoverHelp).toHaveLength(1);
      # also verify that the message is correct about client state and upload state
      expect($hoverHelp.find('.client-state .msg')).toContainText('MISSING')
      expect($hoverHelp.find('.upload-state .msg')).toContainText('PENDING UPLOAD')

      $uploadState.btOff()

