import expect from 'expect';
import fetchMock from 'fetch-mock';

import {
  CHANNEL,
  CHANNEL_ID,
  STREAM_ID,
  WRONG_CHANNEL_STREAM_ID,
  LTV_VOD_DATA,
  PARSED_LTV_VOD,
  mockOnlineChannelWithTargetStream,
  mockOnlineChannelWithDifferentStreamWithTargetVOD,
  mockOfflineChannelWithTargetVOD,
  mockOfflineChannelWithoutTargetVOD,
  mockVODExistsButStreamIsForDifferentChannel,
} from 'mtest/fetchMocks/liveToVODStatus';

import {
  fetchLiveToVODStatus,
  GO_TO_CHANNEL_STATUS,
  GO_TO_VOD_STATUS,
  parseVODResponse,
} from 'mweb/common/fetch/liveToVODStatus';
import { formatVideoLength } from 'mweb/common/utils/formatVideoLength';
import { VideoType } from 'mweb/common/reducers/data/baseVideoDetails';

describe('fetchLiveToVODStatus', () => {
  afterEach(() => {
    expect(fetchMock.done()).toEqual(true);
    fetchMock.restore();
  });

  it('returns the proper payload when channel is online with target stream', () => {
    mockOnlineChannelWithTargetStream();

    return fetchLiveToVODStatus(CHANNEL_ID, STREAM_ID).then(payload => {
      expect(payload).toEqual({
        status: GO_TO_CHANNEL_STATUS,
        channel: CHANNEL,
        streamID: STREAM_ID,
      });
    });
  });

  it('returns the proper payload when channel is online with different stream and vod exists', () => {
    mockOnlineChannelWithDifferentStreamWithTargetVOD();

    return fetchLiveToVODStatus(CHANNEL_ID, STREAM_ID).then(payload => {
      expect(payload).toEqual({
        status: GO_TO_VOD_STATUS,
        channel: CHANNEL,
        vod: PARSED_LTV_VOD,
      });
    });
  });

  it('returns the proper payload when channel is offline and vod exists for target stream', () => {
    mockOfflineChannelWithTargetVOD();

    return fetchLiveToVODStatus(CHANNEL_ID, STREAM_ID).then(payload => {
      expect(payload).toEqual({
        status: GO_TO_VOD_STATUS,
        channel: CHANNEL,
        vod: PARSED_LTV_VOD,
      });
    });
  });

  it('returns the proper payload when channel is offline and there is no vod for target stream', () => {
    mockOfflineChannelWithoutTargetVOD();

    return fetchLiveToVODStatus(CHANNEL_ID, STREAM_ID).then(payload => {
      expect(payload).toEqual({
        status: GO_TO_CHANNEL_STATUS,
        channel: CHANNEL,
        streamID: undefined,
      });
    });
  });

  it('returns the proper payload when target stream is for different channel', () => {
    mockVODExistsButStreamIsForDifferentChannel();

    return fetchLiveToVODStatus(
      CHANNEL_ID,
      WRONG_CHANNEL_STREAM_ID,
    ).then(payload => {
      expect(payload).toEqual({
        status: GO_TO_CHANNEL_STATUS,
        channel: CHANNEL,
        streamID: undefined,
      });
    });
  });
});

describe('parseVODResponse', () => {
  it('builds the correct payload from the JSON', () => {
    expect(parseVODResponse(LTV_VOD_DATA)).toEqual({
      videoType: VideoType.Archive,
      channel: LTV_VOD_DATA.channel.name,
      description: LTV_VOD_DATA.description,
      game: undefined,
      id: LTV_VOD_DATA._id.slice(1),
      title: LTV_VOD_DATA.title,
      length: LTV_VOD_DATA.length,
      thumbnailURL: LTV_VOD_DATA.preview,
      viewCount: LTV_VOD_DATA.views,
      formattedLength: formatVideoLength(LTV_VOD_DATA.length),
      date: new Date(LTV_VOD_DATA.recorded_at).valueOf(),
    });
  });
});
