/**
 * @license
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed 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 '../../../test/common-test-setup-karma.js';
import './gr-cursor-manager.js';
import {html} from '@polymer/polymer/lib/utils/html-tag.js';
import {CursorMoveResult} from './gr-cursor-manager.js';

const basicTestFixutre = fixtureFromTemplate(html`
    <gr-cursor-manager cursor-target-class="targeted"></gr-cursor-manager>
    <ul>
      <li>A</li>
      <li>B</li>
      <li>C</li>
      <li>D</li>
    </ul>
`);

suite('gr-cursor-manager tests', () => {
  let element;
  let list;

  setup(() => {
    const fixtureElements = basicTestFixutre.instantiate();
    element = fixtureElements[0];
    list = fixtureElements[1];
  });

  test('core cursor functionality', () => {
    // The element is initialized into the proper state.
    assert.isArray(element.stops);
    assert.equal(element.stops.length, 0);
    assert.equal(element.index, -1);
    assert.isNotOk(element.target);

    // Initialize the cursor with its stops.
    element.stops = list.querySelectorAll('li');

    // It should have the stops but it should not be targeting any of them.
    assert.isNotNull(element.stops);
    assert.equal(element.stops.length, 4);
    assert.equal(element.index, -1);
    assert.isNotOk(element.target);

    // Select the third stop.
    element.setCursor(list.children[2]);

    // It should update its internal state and update the element's class.
    assert.equal(element.index, 2);
    assert.equal(element.target, list.children[2]);
    assert.isTrue(list.children[2].classList.contains('targeted'));
    assert.isFalse(element.isAtStart());
    assert.isFalse(element.isAtEnd());

    // Progress the cursor.
    let result = element.next();

    // Confirm that the next stop is selected and that the previous stop is
    // unselected.
    assert.equal(result, CursorMoveResult.MOVED);
    assert.equal(element.index, 3);
    assert.equal(element.target, list.children[3]);
    assert.isTrue(element.isAtEnd());
    assert.isFalse(list.children[2].classList.contains('targeted'));
    assert.isTrue(list.children[3].classList.contains('targeted'));

    // Progress the cursor.
    result = element.next();

    // We should still be at the end.
    assert.equal(result, CursorMoveResult.CLIPPED);
    assert.equal(element.index, 3);
    assert.equal(element.target, list.children[3]);
    assert.isTrue(element.isAtEnd());

    // Wind the cursor all the way back to the first stop.
    result = element.previous();
    assert.equal(result, CursorMoveResult.MOVED);
    result = element.previous();
    assert.equal(result, CursorMoveResult.MOVED);
    result = element.previous();
    assert.equal(result, CursorMoveResult.MOVED);

    // The element state should reflect the start of the list.
    assert.equal(element.index, 0);
    assert.equal(element.target, list.children[0]);
    assert.isTrue(element.isAtStart());
    assert.isTrue(list.children[0].classList.contains('targeted'));

    const newLi = document.createElement('li');
    newLi.textContent = 'Z';
    list.insertBefore(newLi, list.children[0]);
    element.stops = list.querySelectorAll('li');

    assert.equal(element.index, 1);

    // De-select all targets.
    element.unsetCursor();

    // There should now be no cursor target.
    assert.isFalse(list.children[1].classList.contains('targeted'));
    assert.isNotOk(element.target);
    assert.equal(element.index, -1);
  });

  test('next() goes to first element when no cursor is set', () => {
    element.stops = list.querySelectorAll('li');
    const result = element.next();

    assert.equal(result, CursorMoveResult.MOVED);
    assert.equal(element.index, 0);
    assert.equal(element.target, list.children[0]);
    assert.isTrue(list.children[0].classList.contains('targeted'));
    assert.isTrue(element.isAtStart());
    assert.isFalse(element.isAtEnd());
  });

  test('next() resets the cursor when there are no stops', () => {
    element.stops = [];
    const result = element.next();

    assert.equal(result, CursorMoveResult.NO_STOPS);
    assert.equal(element.index, -1);
    assert.isNotOk(element.target);
    assert.isFalse(list.children[1].classList.contains('targeted'));
    assert.isFalse(element.isAtStart());
    assert.isFalse(element.isAtEnd());
  });

  test('next() with abort', () => {
    element.stops = list.querySelectorAll('li');
    element.setCursor(list.children[0]);

    const result = element.next({abort: row => row.textContent === 'B'});

    assert.equal(result, CursorMoveResult.ABORTED);
    assert.equal(element.index, 0);
  });

  test('next() aborts even when stop would be filtered', () => {
    element.stops = list.querySelectorAll('li');
    element.setCursor(list.children[0]);

    const result = element.next({
      abort: row => row.textContent === 'B',
      filter: row => row.textContent === 'C',
    });

    assert.equal(result, CursorMoveResult.ABORTED);
    assert.equal(element.index, 0);
  });

  test('previous() goes to last element when no cursor is set', () => {
    element.stops = list.querySelectorAll('li');
    const result = element.previous();

    assert.equal(result, CursorMoveResult.MOVED);
    const lastIndex = list.children.length - 1;
    assert.equal(element.index, lastIndex);
    assert.equal(element.target, list.children[lastIndex]);
    assert.isTrue(list.children[lastIndex].classList.contains('targeted'));
    assert.isFalse(element.isAtStart());
    assert.isTrue(element.isAtEnd());
  });

  test('previous() resets the cursor when there are no stops', () => {
    element.stops = [];
    const result = element.previous();

    assert.equal(result, CursorMoveResult.NO_STOPS);
    assert.equal(element.index, -1);
    assert.isNotOk(element.target);
    assert.isFalse(list.children[1].classList.contains('targeted'));
    assert.isFalse(element.isAtStart());
    assert.isFalse(element.isAtEnd());
  });

  test('_moveCursor', () => {
    // Initialize the cursor with its stops.
    element.stops = list.querySelectorAll('li');
    // Select the first stop.
    element.setCursor(list.children[0]);
    const getTargetHeight = sinon.stub();

    // Move the cursor without an optional get target height function.
    element._moveCursor(1);
    assert.isFalse(getTargetHeight.called);

    // Move the cursor with an optional get target height function.
    element._moveCursor(1, {getTargetHeight});
    assert.isTrue(getTargetHeight.called);
  });

  test('_moveCursor from for invalid index does not check height', () => {
    element.stops = [];
    const getTargetHeight = sinon.stub();
    element._moveCursor(1, () => false, {getTargetHeight});
    assert.isFalse(getTargetHeight.called);
  });

  test('setCursorAtIndex with noScroll', () => {
    sinon.stub(element, '_targetIsVisible').callsFake(() => false);
    const scrollStub = sinon.stub(window, 'scrollTo');
    element.stops = list.querySelectorAll('li');
    element.scrollMode = 'keep-visible';

    element.setCursorAtIndex(1, true);
    assert.isFalse(scrollStub.called);

    element.setCursorAtIndex(2);
    assert.isTrue(scrollStub.called);
  });

  test('move with filter', () => {
    const isLetterB = function(row) {
      return row.textContent === 'B';
    };
    element.stops = list.querySelectorAll('li');
    // Start cursor at the first stop.
    element.setCursor(list.children[0]);

    // Move forward to meet the next condition.
    element.next({filter: isLetterB});
    assert.equal(element.index, 1);

    // Nothing else meets the condition, should be at last stop.
    element.next({filter: isLetterB});
    assert.equal(element.index, 3);

    // Should stay at last stop if try to proceed.
    element.next({filter: isLetterB});
    assert.equal(element.index, 3);

    // Go back to the previous condition met. Should be back at.
    // stop 1.
    element.previous({filter: isLetterB});
    assert.equal(element.index, 1);

    // Go back. No more meet the condition. Should be at stop 0.
    element.previous({filter: isLetterB});
    assert.equal(element.index, 0);
  });

  test('focusOnMove prop', () => {
    const listEls = list.querySelectorAll('li');
    for (let i = 0; i < listEls.length; i++) {
      sinon.spy(listEls[i], 'focus');
    }
    element.stops = listEls;
    element.setCursor(list.children[0]);

    element.focusOnMove = false;
    element.next();
    assert.isFalse(element.target.focus.called);

    element.focusOnMove = true;
    element.next();
    assert.isTrue(element.target.focus.called);
  });

  suite('_scrollToTarget', () => {
    let scrollStub;
    setup(() => {
      element.stops = list.querySelectorAll('li');
      element.scrollMode = 'keep-visible';

      // There is a target which has a targetNext
      element.setCursor(list.children[0]);
      element._moveCursor(1);
      scrollStub = sinon.stub(window, 'scrollTo');
      window.innerHeight = 60;
    });

    test('Called when top and bottom not visible', () => {
      sinon.stub(element, '_targetIsVisible').returns(false);
      element._scrollToTarget();
      assert.isTrue(scrollStub.called);
    });

    test('Not called when top and bottom visible', () => {
      sinon.stub(element, '_targetIsVisible').returns(true);
      element._scrollToTarget();
      assert.isFalse(scrollStub.called);
    });

    test('Called when top is visible, bottom is not, scroll is lower', () => {
      const visibleStub = sinon.stub(element, '_targetIsVisible').callsFake(
          () => visibleStub.callCount === 2);
      sinon.stub(element, '_getWindowDims').returns({
        scrollX: 123,
        scrollY: 15,
        innerHeight: 1000,
        pageYOffset: 0,
      });
      sinon.stub(element, '_calculateScrollToValue').returns(20);
      element._scrollToTarget();
      assert.isTrue(scrollStub.called);
      assert.isTrue(scrollStub.calledWithExactly(123, 20));
      assert.equal(visibleStub.callCount, 2);
    });

    test('Called when top is visible, bottom not, scroll is higher', () => {
      const visibleStub = sinon.stub(element, '_targetIsVisible').callsFake(
          () => visibleStub.callCount === 2);
      sinon.stub(element, '_getWindowDims').returns({
        scrollX: 123,
        scrollY: 25,
        innerHeight: 1000,
        pageYOffset: 0,
      });
      sinon.stub(element, '_calculateScrollToValue').returns(20);
      element._scrollToTarget();
      assert.isFalse(scrollStub.called);
      assert.equal(visibleStub.callCount, 2);
    });

    test('_calculateScrollToValue', () => {
      sinon.stub(element, '_getWindowDims').returns({
        scrollX: 123,
        scrollY: 25,
        innerHeight: 300,
        pageYOffset: 0,
      });
      assert.equal(element._calculateScrollToValue(1000, {offsetHeight: 10}),
          905);
    });
  });
});
