package org.icij.extract.spewer;

import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.tika.metadata.Metadata;
import org.icij.extract.document.Document;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.Reader;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

public class RESTSpewer extends Spewer {
	private static final Logger logger = LoggerFactory.getLogger(RESTSpewer.class);

	private final CloseableHttpClient client;
	private final URI uri;

	RESTSpewer(final FieldNames fields, final CloseableHttpClient client, final URI uri) {
		super(fields);
		this.client = client;
		this.uri = uri;
	}

	@Override
	public void write(final Document document, final Reader reader) throws IOException {
		final HttpPut put = new HttpPut(uri.resolve(document.getId()));
		final List<NameValuePair> params = new ArrayList<>();

		params.add(new BasicNameValuePair(fields.forId(), document.getId()));
		params.add(new BasicNameValuePair(fields.forPath(), document.getPath().toString()));
		params.add(new BasicNameValuePair(fields.forText(), toString(reader)));

		if (outputMetadata) {
			final Metadata metadata = document.getMetadata();

			for (String name : metadata.names()) {
				params.add(new BasicNameValuePair(fields.forMetadata(name), metadata.get(name)));
			}
		}

		put.setEntity(new UrlEncodedFormEntity(params, StandardCharsets.UTF_8));
		put(put);
	}

	@Override
	public void writeMetadata(final Document document) throws IOException {
		final HttpPut put = new HttpPut(uri.resolve(document.getId()));
		final List<NameValuePair> params = new ArrayList<>();

		final Metadata metadata = document.getMetadata();

		for (String name : metadata.names()) {
			params.add(new BasicNameValuePair(fields.forMetadata(name), metadata.get(name)));
		}

		put.setEntity(new UrlEncodedFormEntity(params, StandardCharsets.UTF_8));
		put(put);
	}

	@Override
	public void close() throws IOException {
		client.close();
	}

	private void put(final HttpPut put) throws IOException {
		logger.info(String.format("Writing to \"%s\".", put.getURI()));

		try (final CloseableHttpResponse response = client.execute(put)) {
			final int code = response.getStatusLine().getStatusCode();

			if (code < 200 || code >= 300) {
				throw new SpewerException(String.format("Unexpected response code: %d", code));
			}
		}
	}
}

@@ -1475,34 +1475,28 @@
 %0A%09%09%09
-final Metadata m
+parametrizeM
 etadata
- = 
+(
 docu
@@ -1517,143 +1517,18 @@
 ta()
-;%0A%0A%09%09%09for (String name : metadata.names()) %7B%0A%09%09%09%09params.add(new BasicNameValuePair(fields.forMetadata(name), metadata.get(name)));%0A%09%09%09%7D
+, params);
 %0A%09%09%7D
@@ -1833,34 +1833,28 @@
 %0A%0A%09%09
-final Metadata m
+parametrizeM
 etadata
- = 
+(
 docu
@@ -1875,141 +1875,18 @@
 ta()
-;%0A%0A%09%09for (String name : metadata.names()) %7B%0A%09%09%09params.add(new BasicNameValuePair(fields.forMetadata(name), metadata.get(name)));%0A%09%09%7D%0A
+, params);
 %0A%09%09p
@@ -2048,16 +2048,344 @@
 ();%0A%09%7D%0A%0A
+%09private void parametrizeMetadata(final Metadata metadata, final List%3CNameValuePair%3E params) throws SpewerException %7B%0A%09%09applyMetadata(metadata, (name, value)-%3E params.add(new BasicNameValuePair(name, value)), (name, values)-%3E %7B%0A%09%09%09for (String value: values) %7B%0A%09%09%09%09params.add(new BasicNameValuePair(name, value));%0A%09%09%09%7D%0A%09%09%7D);%0A%09%7D%0A%0A
 %09private

Use super method for formatted metadata