/* eslint-disable prettier/prettier */
/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable node/no-unpublished-import */
/*---------------------------------------------------------
 * Copyright 2020 The Go Authors. All rights reserved.
 * Licensed under the MIT License. See LICENSE in the project root for license information.
 *--------------------------------------------------------*/

import assert from 'assert';
import { describe, it } from 'mocha';
import * as sinon from 'sinon';
import * as vscode from 'vscode';
import { getLatestGoVersions, GoEnvironmentOption, latestGoVersionKey } from '../../src/goEnvironmentStatus';
import { getGlobalState, setGlobalState, updateGlobalState } from '../../src/stateUtils';
import { MockMemento } from '../mocks/MockMemento';

import moment = require('moment');
import semver = require('semver');
import WebRequest = require('web-request');

describe('#getLatestGoVersion()', function () {
	this.timeout(40000);
	let sandbox: sinon.SinonSandbox | undefined;
	let defaultMemento: vscode.Memento;
	const webrequest = sinon.mock(WebRequest);
	const mmnt = sinon.mock(moment);

	const now = 100000000;
	const oneday = 60 * 60 * 24 * 1000; // 24 hours in milliseconds

	this.beforeAll(async () => {
		defaultMemento = getGlobalState();
	});
	this.afterAll(async () => {
		setGlobalState(defaultMemento);
	});

	this.beforeEach(() => {
		sandbox = sinon.createSandbox();
		setGlobalState(new MockMemento());

		webrequest
			.expects('json')
			.withArgs('https://go.dev/dl/?mode=json')
			.returns([
				{
					version: 'go1.15.1',
					stable: true
				},
				{
					version: 'go1.14.2',
					stable: true
				}
			]);

		mmnt.expects('now').returns(now);
	});

	this.afterEach(async () => {
		sandbox!.restore();
	});

	it('should get latest go versions from golang.org/dl with empty cache', async () => {
		const results = await getLatestGoVersions();
		const want = [
			{ label: 'Go 1.15.1', binpath: 'golang.org/dl/go1.15.1' },
			{ label: 'Go 1.14.2', binpath: 'golang.org/dl/go1.14.2' }
		];

		assert.strictEqual(results.length, want.length);
		for (let i = 0; i < results.length; i++) {
			assert(results[i].label === want[i].label);
			assert(results[i].binpath === want[i].binpath);
		}
	});

	const cacheVersions = [
		new GoEnvironmentOption('golang.org/dl/go1.14.7', 'Go 1.14.7', false),
		new GoEnvironmentOption('golang.org/dl/go1.13.2', 'Go 1.13.2', false)
	];

	it('should get latest go versions from golang.org/dl with timed out cache', async () => {
		// add a timed out cache entry
		await updateGlobalState(latestGoVersionKey, {
			timestamp: now - (oneday + 1), // more than one day ago
			goVersions: cacheVersions
		});

		// run test
		const results = await getLatestGoVersions();
		const want = [
			{ label: 'Go 1.15.1', binpath: 'golang.org/dl/go1.15.1' },
			{ label: 'Go 1.14.2', binpath: 'golang.org/dl/go1.14.2' }
		];

		// check results
		assert.strictEqual(results.length, want.length);
		for (let i = 0; i < results.length; i++) {
			assert(results[i].label === want[i].label);
			assert(results[i].binpath === want[i].binpath);
		}
	});

	it('should get latest go versions from cache', async () => {
		// add a valid cache entry
		await updateGlobalState(latestGoVersionKey, {
			timestamp: now - (oneday - 100), // less than one day ago
			goVersions: cacheVersions
		});

		// run test
		const results = await getLatestGoVersions();
		const want = [
			{ label: 'Go 1.14.7', binpath: 'golang.org/dl/go1.14.7' },
			{ label: 'Go 1.13.2', binpath: 'golang.org/dl/go1.13.2' }
		];

		// check results
		assert(results.length === want.length);
		for (let i = 0; i < results.length; i++) {
			assert(results[i].label === want[i].label);
			assert(results[i].binpath === want[i].binpath);
		}
	});
});
