/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

package org.apache.sysds.test.functions.federated.transform;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;

import org.apache.sysds.common.Types;
import org.apache.sysds.common.Types.ExecMode;
import org.apache.sysds.runtime.io.FrameReader;
import org.apache.sysds.runtime.io.FrameReaderFactory;
import org.apache.sysds.runtime.matrix.data.FrameBlock;
import org.apache.sysds.test.AutomatedTestBase;
import org.apache.sysds.test.TestConfiguration;
import org.apache.sysds.test.TestUtils;
import org.junit.Assert;
import org.junit.Test;

public class TransformFederatedEncodeDecodeTest extends AutomatedTestBase {
	private static final String TEST_NAME1 = "TransformFederatedEncodeDecode";
	private static final String TEST_DIR = "functions/transform/";
	private static final String TEST_CLASS_DIR = TEST_DIR+TransformFederatedEncodeDecodeTest.class.getSimpleName()+"/";

	private static final String SPEC = "TransformEncodeDecodeSpec.json";

	private static final int rows = 1234;
	private static final int cols = 2;
	private static final double sparsity1 = 0.9;
	private static final double sparsity2 = 0.1;

	@Override
	public void setUp() {
		TestUtils.clearAssertionInformation();
		addTestConfiguration(TEST_NAME1,
			new TestConfiguration(TEST_CLASS_DIR, TEST_NAME1, new String[] {"FO1", "FO2"}));
	}

	@Test
	public void runTestCSVDenseCP() {
		runTransformEncodeDecodeTest(false, Types.FileFormat.CSV);
	}

	@Test
	public void runTestCSVSparseCP() {
		runTransformEncodeDecodeTest(true, Types.FileFormat.CSV);
	}

	@Test
	public void runTestTextcellDenseCP() {
		runTransformEncodeDecodeTest(false, Types.FileFormat.TEXT);
	}

	@Test
	public void runTestTextcellSparseCP() {
		runTransformEncodeDecodeTest(true, Types.FileFormat.TEXT);
	}

	@Test
	public void runTestBinaryDenseCP() {
		runTransformEncodeDecodeTest(false, Types.FileFormat.BINARY);
	}

	@Test
	public void runTestBinarySparseCP() {
		runTransformEncodeDecodeTest(true, Types.FileFormat.BINARY);
	}

	private void runTransformEncodeDecodeTest(boolean sparse, Types.FileFormat format) {
		ExecMode platformOld = rtplatform;
		rtplatform = ExecMode.SINGLE_NODE;

		Thread t1 = null, t2 = null, t3 = null, t4 = null;
		try {
			getAndLoadTestConfiguration(TEST_NAME1);

			int port1 = getRandomAvailablePort();
			t1 = startLocalFedWorkerThread(port1);
			int port2 = getRandomAvailablePort();
			t2 = startLocalFedWorkerThread(port2);
			int port3 = getRandomAvailablePort();
			t3 = startLocalFedWorkerThread(port3);
			int port4 = getRandomAvailablePort();
			t4 = startLocalFedWorkerThread(port4);

			// schema
			Types.ValueType[] schema = new Types.ValueType[cols / 2];
			Arrays.fill(schema, Types.ValueType.FP64);
			// generate and write input data
			// A is the data that will be aggregated and not recoded
			double[][] A = TestUtils.round(getRandomMatrix(rows, cols / 2, 1, 15, sparse ? sparsity2 : sparsity1, 7));
			double[][] AUpper = Arrays.copyOf(A, rows / 2);
			double[][] ALower = Arrays.copyOfRange(A, rows / 2, rows);
			writeInputFrameWithMTD("AU", AUpper, false, schema, format);
			writeInputFrameWithMTD("AL", ALower, false, schema, format);

			// B will be recoded and will be the column that will be grouped by
			Arrays.fill(schema, Types.ValueType.STRING);
			// we set sparsity to 1.0 to ensure all the string labels exist
			double[][] B = TestUtils.round(getRandomMatrix(rows, cols / 2, 1, 15, 1.0, 8));
			double[][] BUpper = Arrays.copyOf(B, rows / 2);
			double[][] BLower = Arrays.copyOfRange(B, rows / 2, rows);
			writeInputFrameWithMTD("BU", BUpper, false, schema, format);
			writeInputFrameWithMTD("BL", BLower, false, schema, format);

			fullDMLScriptName = SCRIPT_DIR + TEST_DIR + TEST_NAME1 + ".dml";

			programArgs = new String[] {"-nvargs",
				"in_AU=" + TestUtils.federatedAddress("localhost", port1, input("AU")),
				"in_AL=" + TestUtils.federatedAddress("localhost", port2, input("AL")),
				"in_BU=" + TestUtils.federatedAddress("localhost", port3, input("BU")),
				"in_BL=" + TestUtils.federatedAddress("localhost", port4, input("BL")), "rows=" + rows, "cols=" + cols,
				"spec_file=" + SCRIPT_DIR + TEST_DIR + SPEC, "out1=" + output("FO1"), "out2=" + output("FO2"),
				"format=" + format.toString()};

			// run test
			runTest(true, false, null, -1);

			// compare frame before and after encode and decode
			FrameReader reader = FrameReaderFactory.createFrameReader(format);
			FrameBlock OUT = reader.readFrameFromHDFS(output("FO2"), rows, cols);
			for(int r = 0; r < rows; r++) {
				for(int c = 0; c < cols; c++) {
					String expected = c < cols / 2 ? Double.toString(A[r][c]) : "Str" + B[r][c - cols / 2];
					String val = (String) OUT.get(r, c);
					Assert.assertEquals("Enc- and Decoded frame does not match the source frame: " + expected + " vs "
						+ val, expected, val);
				}
			}
			// TODO federate the aggregated result so that the decode is applied in a federated environment
			// compare matrices (values recoded to identical codes)
			FrameBlock FO = reader.readFrameFromHDFS(output("FO1"), 15, 2);
			HashMap<String, Long> cFA = getCounts(A, B);
			Iterator<String[]> iterFO = FO.getStringRowIterator();
			while(iterFO.hasNext()) {
				String[] row = iterFO.next();
				Double expected = (double) cFA.get(row[1]);
				Double val = (row[0] != null) ? Double.parseDouble(row[0]) : 0;
				Assert.assertEquals("Output aggregates don't match: " + expected + " vs " + val, expected, val);
			}
		}
		catch(Exception ex) {
			ex.printStackTrace();
			Assert.fail(ex.getMessage());
		}
		finally {
			TestUtils.shutdownThread(t1);
			TestUtils.shutdownThread(t2);
			TestUtils.shutdownThread(t3);
			TestUtils.shutdownThread(t4);
			rtplatform = platformOld;
		}
	}

	private static HashMap<String, Long> getCounts(double[][] countFrame, double[][] groupFrame) {
		HashMap<String, Long> ret = new HashMap<>();
		for(int i = 0; i < countFrame.length; i++) {
			String key = "Str" + groupFrame[i][0];
			Long tmp = ret.get(key);
			ret.put(key, (tmp != null) ? tmp + 1 : 1);
		}
		return ret;
	}
}
