/********************************************************************************
 * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
 *
 * See the NOTICE file(s) distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 ********************************************************************************/

package org.eclipse.mdm.businessobjects.boundary;

import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasItems;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Collection;
import java.util.Map;
import java.util.Optional;

import javax.ejb.EJB;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.ws.rs.core.Application;

import org.eclipse.mdm.api.base.adapter.ChildrenStore;
import org.eclipse.mdm.api.base.adapter.Core;
import org.eclipse.mdm.api.base.adapter.EntityStore;
import org.eclipse.mdm.api.base.adapter.RelationStore;
import org.eclipse.mdm.api.base.file.FileService;
import org.eclipse.mdm.api.base.model.ContextType;
import org.eclipse.mdm.api.base.model.Entity;
import org.eclipse.mdm.api.base.model.Enumeration;
import org.eclipse.mdm.api.base.model.FileLink;
import org.eclipse.mdm.api.base.model.MimeType;
import org.eclipse.mdm.api.base.model.Test;
import org.eclipse.mdm.api.base.model.User;
import org.eclipse.mdm.api.base.model.Value;
import org.eclipse.mdm.api.base.model.ValueType;
import org.eclipse.mdm.api.dflt.ApplicationContext;
import org.eclipse.mdm.api.dflt.model.EntityFactory;
import org.eclipse.mdm.api.dflt.model.Pool;
import org.eclipse.mdm.api.dflt.model.Project;
import org.eclipse.mdm.businessobjects.control.FileLinkActivity;
import org.eclipse.mdm.businessobjects.service.EntityService;
import org.eclipse.mdm.connector.boundary.ConnectorService;
import org.glassfish.hk2.api.Factory;
import org.glassfish.hk2.api.Injectee;
import org.glassfish.hk2.api.InjectionResolver;
import org.glassfish.hk2.api.ServiceHandle;
import org.glassfish.hk2.api.ServiceLocator;
import org.glassfish.hk2.api.TypeLiteral;
import org.glassfish.hk2.utilities.binding.AbstractBinder;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Before;
import org.junit.Ignore;

import com.google.common.collect.ImmutableMap;

import io.restassured.RestAssured;
import io.vavr.control.Try;

public class FileLinkActivityTest extends JerseyTest {

	public static final String ENV = "MDM";
	public static final FileLink[] FILE_LINKS = new FileLink[] {
			FileLink.newRemote("dir/test.txt", new MimeType("text/plain"), "Just a text file"),
			FileLink.newRemote("dir/subdir/test.bin", new MimeType("application/octet-stream"), "A binary file"),
			FileLink.newRemote("dir/specialCharsßä#&'.bin", new MimeType("application/octet-stream"),
					"A binary file") };

	private ConnectorService connectorService = mock(ConnectorService.class);
	private ApplicationContext context = mock(ApplicationContext.class);
	private FileService fileService = mock(FileService.class);

	private EntityService entityService = mock(EntityService.class);

	@Override
	protected Application configure() {

		AbstractBinder binder = new AbstractBinder() {

			@Override
			protected void configure() {
				bind(EJBInjectResolver.class).to(new TypeLiteral<InjectionResolver<EJB>>() {
				}).in(Singleton.class);
				bind(TestService.class).to(TestService.class);
				bindFactory(new InstanceFactory<EntityService>(entityService)).to(EntityService.class);
				bindFactory(new InstanceFactory<ConnectorService>(connectorService)).to(ConnectorService.class);
				bind(FileLinkActivity.class).to(FileLinkActivity.class);

			}
		};

		return new ResourceConfig(TestResource.class, TestStepResource.class, MeasurementResource.class)
				.register(binder);
	}

	@Before
	public void init() throws IOException {
		RestAssured.baseURI = target().getUri().toString();

		final Test test = createTest(FILE_LINKS);

		when(entityService.find(any(), eq(Test.class), any())).thenReturn(Try.of(() -> test));

		when(connectorService.getContextByName(eq(ENV))).thenReturn(context);
		when(context.getFileService()).thenReturn(Optional.of(fileService));
		when(fileService.openStream(eq(test), eq(FILE_LINKS[0])))
				.thenReturn(new ByteArrayInputStream("Some text".getBytes()));
		when(fileService.openStream(eq(test), eq(FILE_LINKS[2])))
				.thenReturn(new ByteArrayInputStream("xyz".getBytes()));
	}

	@Ignore
	@org.junit.Test
	public void testMDMLinksAttribute() {
		// request test and check MDMLinks attribute
		RestAssured.given().pathParam("SOURCENAME", ENV).pathParam("TESTID", "1").when()
				.get("/environments/{SOURCENAME}/tests/{TESTID}").then().statusCode(200)
				.body("data.get(0).attributes.find { it.get('name') == 'MDMLinks' }.value.remotePath",
						hasItems("dir/test.txt", "dir/subdir/test.bin", "dir/specialCharsßä#&'.bin"))
				.and()
				.body("data.get(0).attributes.find { it.get('name') == 'MDMLinks' }.value.description",
						hasItems("Just a text file", "A binary file", "A binary file"))
				.and().body("data.get(0).attributes.find { it.get('name') == 'MDMLinks' }.value.mimeType",
						hasItems("text/plain", "application/octet-stream", "application/octet-stream"));
	}

	@Ignore
	@org.junit.Test
	public void testFileDownload() {
		RestAssured.given().pathParam("SOURCENAME", ENV).pathParam("TESTID", "1")
				.pathParam("REMOTE_PATH", "dir/test.txt").when()
				.get("/environments/{SOURCENAME}/tests/{TESTID}/files/{REMOTE_PATH}").then().statusCode(200)
				.contentType("text/plain").body(equalTo("Some text"));
	}

	@Ignore
	@org.junit.Test
	public void testFileDownloadWithSpecialChars() {
		RestAssured.given().pathParam("SOURCENAME", ENV).pathParam("TESTID", "1")
				.pathParam("REMOTE_PATH", "dir/specialCharsßä#&'.bin").when()
				.get("/environments/{SOURCENAME}/tests/{TESTID}/files/{REMOTE_PATH}").then().statusCode(200)
				.contentType("application/octet-stream").body(equalTo("xyz"));
	}

	private Test createTest(FileLink[] fileLinks) {
		EntityFactory factory = new JUnitEntityFactory() {
			@Override
			protected <T extends Entity> Core createCore(Class<T> entityClass) {
				return new CoreImpl(ImmutableMap.of("Name", ValueType.STRING.create("test"), "DateCreated",
						ValueType.DATE.create("DateCreated"), "MDMLinks",
						ValueType.FILE_LINK_SEQUENCE.create("MDMLinks", fileLinks)));
			}
		};

		final Project project = factory.createProject("MyProject");
		final Pool pool = factory.createPool("MyPool", project);
		return factory.createTest("MyTest", pool);
	}

	public static class EJBInjectResolver implements InjectionResolver<EJB> {

		@Inject
		private ServiceLocator locator;

		@Override
		public Object resolve(Injectee injectee, ServiceHandle<?> root) {
			return locator.getService(injectee.getRequiredType());
		}

		@Override
		public boolean isConstructorParameterIndicator() {
			return false;
		}

		@Override
		public boolean isMethodParameterIndicator() {
			return false;
		}
	}

	private class JUnitEntityFactory extends EntityFactory {

		@Override
		protected Optional<User> getLoggedInUser() {
			return Optional.empty();
		}

		@Override
		protected <T extends Entity> Core createCore(Class<T> entityClass) {
			// noop
			return null;
		}

		@Override
		protected void validateEnum(Enumeration<?> enumerationObj) {
			// noop
		}

		@Override
		protected <T extends Entity> Core createCore(Class<T> entityClass, ContextType contextType) {
			// noop
			return null;
		}

		@Override
		protected <T extends Entity> Core createCore(String name, Class<T> entityClass) {
			// noop
			return null;
		}
	}

	public class InstanceFactory<T> implements Factory<T> {

		private T instance;

		public InstanceFactory(T instance) {
			this.instance = instance;
		}

		@Override
		public void dispose(T t) {
		}

		@Override
		public T provide() {
			return instance;
		}

	}

	public class CoreImpl implements Core {

		private Map<String, Value> values;
		private EntityStore mutableStore;

		public CoreImpl(Map<String, Value> values) {
			super();
			this.values = values;
			this.mutableStore = new EntityStore();
		}

		@Override
		public String getSourceName() {
			return "UnitTestSource";
		}

		@Override
		public String getTypeName() {
			return "UnitTestType";
		}

		@Override
		public String getID() {
			return "4711l";
		}

		@Override
		public void setID(String instanceID) {

		}

		@Override
		public Map<String, Value> getValues() {
			return values;
		}

		@Override
		public void hideValues(Collection<String> names) {

		}

		@Override
		public Map<String, Value> getAllValues() {
			return values;
		}

		@Override
		public EntityStore getMutableStore() {
			return mutableStore;
		}

		@Override
		public EntityStore getPermanentStore() {
			return new EntityStore();
		}

		@Override
		public ChildrenStore getChildrenStore() {
			return new ChildrenStore();
		}

		@Override
		public RelationStore getNtoMStore() {
			return new RelationStore();
		}
	}
}
