/*
 * Copyright (C) 2018, Konrad Windszus <konrad_w@gmx.de>
 * and other copyright owners as documented in the project's IP log.
 *
 * This program and the accompanying materials are made available
 * under the terms of the Eclipse Distribution License v1.0 which
 * accompanies this distribution, is reproduced below, and is
 * available at http://www.eclipse.org/org/documents/edl-v10.php
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above
 *   copyright notice, this list of conditions and the following
 *   disclaimer in the documentation and/or other materials provided
 *   with the distribution.
 *
 * - Neither the name of the Eclipse Foundation, Inc. nor the
 *   names of its contributors may be used to endorse or promote
 *   products derived from this software without specific prior
 *   written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package org.eclipse.jgit.internal.transport.http;

import java.io.IOException;
import java.io.InputStream;
import java.io.Writer;
import java.net.HttpCookie;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.time.Instant;
import java.util.Arrays;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;

import org.eclipse.jgit.internal.storage.file.LockFile;
import org.eclipse.jgit.util.http.HttpCookiesMatcher;
import org.hamcrest.CoreMatchers;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

public class NetscapeCookieFileTest {

	@Rule
	public TemporaryFolder folder = new TemporaryFolder();

	private Path tmpFile;

	private URL baseUrl;

	/**
	 * This is the expiration date that is used in the test cookie files
	 */
	private static long JAN_01_2030_NOON = Instant
			.parse("2030-01-01T12:00:00.000Z").toEpochMilli();

	@Before
	public void setUp() throws IOException {
		// this will not only return a new file name but also create new empty
		// file!
		tmpFile = folder.newFile().toPath();
		baseUrl = new URL("http://domain.com/my/path");
	}

	@Test
	public void testMergeCookies() {
		Set<HttpCookie> cookieSet1 = new LinkedHashSet<>();
		HttpCookie cookie = new HttpCookie("key1", "valueFromSet1");
		cookieSet1.add(cookie);
		cookie = new HttpCookie("key2", "valueFromSet1");
		cookieSet1.add(cookie);

		Set<HttpCookie> cookieSet2 = new LinkedHashSet<>();
		cookie = new HttpCookie("key1", "valueFromSet2");
		cookieSet2.add(cookie);
		cookie = new HttpCookie("key3", "valueFromSet2");
		cookieSet2.add(cookie);

		Set<HttpCookie> cookiesExpectedMergedSet = new LinkedHashSet<>();
		cookie = new HttpCookie("key1", "valueFromSet1");
		cookiesExpectedMergedSet.add(cookie);
		cookie = new HttpCookie("key2", "valueFromSet1");
		cookiesExpectedMergedSet.add(cookie);
		cookie = new HttpCookie("key3", "valueFromSet2");
		cookiesExpectedMergedSet.add(cookie);

		Assert.assertThat(
				NetscapeCookieFile.mergeCookies(cookieSet1, cookieSet2),
				HttpCookiesMatcher.containsInOrder(cookiesExpectedMergedSet));

		Assert.assertThat(NetscapeCookieFile.mergeCookies(cookieSet1, null),
				HttpCookiesMatcher.containsInOrder(cookieSet1));
	}

	@Test
	public void testWriteToNewFile() throws IOException {
		Set<HttpCookie> cookies = new LinkedHashSet<>();
		cookies.add(new HttpCookie("key1", "value"));
		// first cookie is a session cookie (and should be ignored)

		HttpCookie cookie = new HttpCookie("key2", "value");
		cookie.setSecure(true);
		cookie.setDomain("mydomain.com");
		cookie.setPath("/");
		cookie.setMaxAge(1000);
		cookies.add(cookie);
		Date creationDate = new Date();
		try (Writer writer = Files.newBufferedWriter(tmpFile,
				StandardCharsets.US_ASCII)) {
			NetscapeCookieFile.write(writer, cookies, baseUrl, creationDate);
		}

		String expectedExpiration = String
				.valueOf(creationDate.getTime() + (cookie.getMaxAge() * 1000));

		Assert.assertThat(
				Files.readAllLines(tmpFile, StandardCharsets.US_ASCII),
				CoreMatchers
						.equalTo(Arrays.asList("mydomain.com\tTRUE\t/\tTRUE\t"
								+ expectedExpiration + "\tkey2\tvalue")));
	}

	@Test
	public void testWriteToExistingFile() throws IOException {
		try (InputStream input = this.getClass()
				.getResourceAsStream("cookies-simple1.txt")) {
			Files.copy(input, tmpFile, StandardCopyOption.REPLACE_EXISTING);
		}

		Set<HttpCookie> cookies = new LinkedHashSet<>();
		HttpCookie cookie = new HttpCookie("key2", "value2");
		cookie.setMaxAge(1000);
		cookies.add(cookie);
		Date creationDate = new Date();
		try (Writer writer = Files.newBufferedWriter(tmpFile,
				StandardCharsets.US_ASCII)) {
			NetscapeCookieFile.write(writer, cookies, baseUrl, creationDate);
		}
		String expectedExpiration = String
				.valueOf(creationDate.getTime() + (cookie.getMaxAge() * 1000));

		Assert.assertThat(
				Files.readAllLines(tmpFile, StandardCharsets.US_ASCII),
				CoreMatchers.equalTo(
						Arrays.asList("domain.com\tTRUE\t/my/path\tFALSE\t"
								+ expectedExpiration + "\tkey2\tvalue2")));
	}

	@Test(expected = IOException.class)
	public void testWriteWhileSomeoneIsHoldingTheLock()
			throws IllegalArgumentException, IOException, InterruptedException {
		try (InputStream input = this.getClass()
				.getResourceAsStream("cookies-simple1.txt")) {
			Files.copy(input, tmpFile, StandardCopyOption.REPLACE_EXISTING);
		}
		NetscapeCookieFile cookieFile = new NetscapeCookieFile(tmpFile);
		// now imitate another process/thread holding the lock file
		LockFile lockFile = new LockFile(tmpFile.toFile());
		try {
			Assert.assertTrue("Could not acquire lock", lockFile.lock());
			cookieFile.write(baseUrl);
		} finally {
			lockFile.unlock();
		}
	}

	@Test
	public void testWriteAfterAnotherJgitProcessModifiedTheFile()
			throws IOException, InterruptedException {
		try (InputStream input = this.getClass()
				.getResourceAsStream("cookies-simple1.txt")) {
			Files.copy(input, tmpFile, StandardCopyOption.REPLACE_EXISTING);
		}
		NetscapeCookieFile cookieFile = new NetscapeCookieFile(tmpFile);
		cookieFile.getCookies(true);
		// now modify file externally
		try (InputStream input = this.getClass()
				.getResourceAsStream("cookies-simple2.txt")) {
			Files.copy(input, tmpFile, StandardCopyOption.REPLACE_EXISTING);
		}
		// now try to write
		cookieFile.write(baseUrl);

		// validate that the external changes are there as well
		// due to rounding errors (conversion from ms to sec to ms)
		// the expiration date might not be exact
		List<String> lines = Files.readAllLines(tmpFile,
				StandardCharsets.US_ASCII);

		Assert.assertEquals("Expected 3 lines", 3, lines.size());
		assertStringMatchesPatternWithInexactNumber(lines.get(0),
				"some-domain1\tTRUE\t/some/path1\tFALSE\t(\\d*)\tkey1\tvalueFromSimple2",
				JAN_01_2030_NOON, 1000);
		assertStringMatchesPatternWithInexactNumber(lines.get(1),
				"some-domain1\tTRUE\t/some/path1\tFALSE\t(\\d*)\tkey3\tvalueFromSimple2",
				JAN_01_2030_NOON, 1000);
		assertStringMatchesPatternWithInexactNumber(lines.get(2),
				"some-domain1\tTRUE\t/some/path1\tFALSE\t(\\d*)\tkey2\tvalueFromSimple1",
				JAN_01_2030_NOON, 1000);
	}

	@SuppressWarnings("boxing")
	private static final void assertStringMatchesPatternWithInexactNumber(
			String string, String pattern, long expectedNumericValue,
			long delta) {
		java.util.regex.Matcher matcher = Pattern.compile(pattern)
				.matcher(string);
		Assert.assertTrue("Given string '" + string + "' does not match '"
				+ pattern + "'", matcher.matches());
		// extract numeric value
		Long actualNumericValue = Long.decode(matcher.group(1));

		Assert.assertTrue(
				"Value is supposed to be close to " + expectedNumericValue
						+ " but is " + actualNumericValue + ".",
				Math.abs(expectedNumericValue - actualNumericValue) <= delta);
	}

	@Test
	public void testWriteAndReadCycle() throws IOException {
		Set<HttpCookie> cookies = new LinkedHashSet<>();

		HttpCookie cookie = new HttpCookie("key1", "value1");
		cookie.setPath("/some/path1");
		cookie.setDomain("some-domain1");
		cookie.setMaxAge(1000);
		cookies.add(cookie);
		cookie = new HttpCookie("key2", "value2");
		cookie.setSecure(true);
		cookie.setPath("/some/path2");
		cookie.setDomain("some-domain2");
		cookie.setMaxAge(1000);
		cookie.setHttpOnly(true);
		cookies.add(cookie);

		Date creationDate = new Date();

		try (Writer writer = Files.newBufferedWriter(tmpFile,
				StandardCharsets.US_ASCII)) {
			NetscapeCookieFile.write(writer, cookies, baseUrl, creationDate);
		}
		Set<HttpCookie> actualCookies = new NetscapeCookieFile(tmpFile,
				creationDate).getCookies(true);
		Assert.assertThat(actualCookies,
				HttpCookiesMatcher.containsInOrder(cookies));
	}

	@Test
	public void testReadAndWriteCycle() throws IOException {
		try (InputStream input = this.getClass()
				.getResourceAsStream("cookies-simple1.txt")) {
			Files.copy(input, tmpFile, StandardCopyOption.REPLACE_EXISTING);
		}
		// round up to the next second (to prevent rounding errors)
		Date creationDate = new Date(
				(System.currentTimeMillis() / 1000) * 1000);
		Set<HttpCookie> cookies = new NetscapeCookieFile(tmpFile, creationDate)
				.getCookies(true);
		Path tmpFile2 = folder.newFile().toPath();
		try (Writer writer = Files.newBufferedWriter(tmpFile2,
				StandardCharsets.US_ASCII)) {
			NetscapeCookieFile.write(writer, cookies, baseUrl, creationDate);
		}
		// compare original file with newly written one, they should not differ
		Assert.assertEquals(Files.readAllLines(tmpFile),
				Files.readAllLines(tmpFile2));
	}

	@Test
	public void testReadWithEmptyAndCommentLines() throws IOException {
		try (InputStream input = this.getClass().getResourceAsStream(
				"cookies-with-empty-and-comment-lines.txt")) {
			Files.copy(input, tmpFile, StandardCopyOption.REPLACE_EXISTING);
		}

		Date creationDate = new Date();
		Set<HttpCookie> cookies = new LinkedHashSet<>();

		HttpCookie cookie = new HttpCookie("key2", "value2");
		cookie.setDomain("some-domain2");
		cookie.setPath("/some/path2");
		cookie.setMaxAge((JAN_01_2030_NOON - creationDate.getTime()) / 1000);
		cookie.setSecure(true);
		cookie.setHttpOnly(true);
		cookies.add(cookie);

		cookie = new HttpCookie("key3", "value3");
		cookie.setDomain("some-domain3");
		cookie.setPath("/some/path3");
		cookie.setMaxAge((JAN_01_2030_NOON - creationDate.getTime()) / 1000);
		cookies.add(cookie);

		Set<HttpCookie> actualCookies = new NetscapeCookieFile(tmpFile, creationDate)
				.getCookies(true);
		Assert.assertThat(actualCookies,
				HttpCookiesMatcher.containsInOrder(cookies));
	}

	@Test
	public void testReadInvalidFile() throws IOException {
		try (InputStream input = this.getClass()
				.getResourceAsStream("cookies-invalid.txt")) {
			Files.copy(input, tmpFile, StandardCopyOption.REPLACE_EXISTING);
		}

		new NetscapeCookieFile(tmpFile)
				.getCookies(true);
	}
}
