/**
 * @license
 * Copyright (C) 2020 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 {html} from '@polymer/polymer/lib/utils/html-tag.js';
import './gr-change-metadata.js';
import {resetPlugins} from '../../../test/test-utils.js';
import {getPluginLoader} from '../../shared/gr-js-api-interface/gr-plugin-loader.js';
import {_testOnly_initGerritPluginApi} from '../../shared/gr-js-api-interface/gr-gerrit.js';
import {stubRestApi} from '../../../test/test-utils.js';

const testHtmlPlugin = document.createElement('dom-module');
testHtmlPlugin.innerHTML = `
    <template>
      <style>
        html {
          --change-metadata-assignee: {
            display: none;
          }
          --change-metadata-label-status: {
            display: none;
          }
          --change-metadata-strategy: {
            display: none;
          }
          --change-metadata-topic: {
            display: none;
          }
        }
      </style>
    </template>
  `;
testHtmlPlugin.register('my-plugin-style');

const basicFixture = fixtureFromTemplate(
    html`<gr-change-metadata mutable="true"></gr-change-metadata>`
);

const pluginApi = _testOnly_initGerritPluginApi();

suite('gr-change-metadata integration tests', () => {
  let element;

  const sectionSelectors = [
    'section.strategy',
    'section.topic',
  ];

  const labels = {
    CI: {
      all: [
        {value: 1, name: 'user 2', _account_id: 1},
        {value: 2, name: 'user '},
      ],
      values: {
        ' 0': 'Don\'t submit as-is',
        '+1': 'No score',
        '+2': 'Looks good to me',
      },
    },
  };

  const getStyle = function(selector, name) {
    return window.getComputedStyle(
        element.root.querySelector(selector))[name];
  };

  function createElement() {
    const element = basicFixture.instantiate();
    element.change = {labels, status: 'NEW'};
    element.revision = {};
    return element;
  }

  setup(() => {
    stubRestApi('getConfig').returns(Promise.resolve({}));
    stubRestApi('getLoggedIn').returns(Promise.resolve(false));
    stubRestApi('deleteVote').returns(Promise.resolve({ok: true}));
  });

  teardown(() => {
    resetPlugins();
  });

  suite('by default', () => {
    setup(done => {
      element = createElement();
      flush(done);
    });

    for (const sectionSelector of sectionSelectors) {
      test(sectionSelector + ' does not have display: none', () => {
        assert.notEqual(getStyle(sectionSelector, 'display'), 'none');
      });
    }
  });

  suite('with plugin style', () => {
    setup(done => {
      resetPlugins();
      pluginApi.install(plugin => {
        plugin.registerStyleModule('change-metadata', 'my-plugin-style');
      }, undefined, 'http://test.com/plugins/style.js');
      element = createElement();
      getPluginLoader().loadPlugins([]);
      getPluginLoader().awaitPluginsLoaded()
          .then(() => {
            flush(done);
          });
    });

    teardown(() => {
      document.body.querySelectorAll('custom-style')
          .forEach(style => style.remove());
    });

    for (const sectionSelector of sectionSelectors) {
      test('section.strategy may have display: none', () => {
        assert.equal(getStyle(sectionSelector, 'display'), 'none');
      });
    }
  });

  suite('label updates', () => {
    let plugin;

    setup(() => {
      pluginApi.install(p => {
        plugin = p;
        plugin.registerStyleModule('change-metadata', 'my-plugin-style');
      }, undefined, 'http://test.com/plugins/style.js');
      sinon.stub(getPluginLoader(), 'arePluginsLoaded').returns(true);
      getPluginLoader().loadPlugins([]);
      element = createElement();
    });

    teardown(() => {
      document.body.querySelectorAll('custom-style')
          .forEach(style => style.remove());
    });

    test('labels changed callback', done => {
      let callCount = 0;
      const labelChangeSpy = sinon.spy(arg => {
        callCount++;
        if (callCount === 1) {
          assert.deepEqual(arg, labels);
          assert.equal(arg.CI.all.length, 2);
          element.set(['change', 'labels'], {
            CI: {
              all: [
                {value: 1, name: 'user 2', _account_id: 1},
              ],
              values: {
                ' 0': 'Don\'t submit as-is',
                '+1': 'No score',
                '+2': 'Looks good to me',
              },
            },
          });
        } else if (callCount === 2) {
          assert.equal(arg.CI.all.length, 1);
          done();
        }
      });

      plugin.changeMetadata().onLabelsChanged(labelChangeSpy);
    });
  });
});
