/*
 * 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.component.compress;

/**
 * Class Containing Testing Constants, for easy enumeration of typical Parameters classes
 */
public class TestConstants {

	private static final int rows[] = {4, 2008, 1283, 5, 1, 251, 5000, 100000, 3123};
	private static final int cols[] = {20, 20, 13, 998, 321, 1, 8, 10, 1};
	private static final double[] sparsityValues = {0.9, 0.1, 0.01, 0.0, 1.0};

	private static final int[] mins = {-10, -127 * 2};
	private static final int[] maxs = {10, 127};

	public enum SparsityType {
		DENSE, SPARSE, ULTRA_SPARSE, EMPTY, FULL
	}

	public enum ValueType {
		RAND, // UC
		CONST, // RLE
		RAND_ROUND, // Values rounded to nearest whole numbers.
		OLE_COMPRESSIBLE, // Ideal inputs for OLE Compression.
		RLE_COMPRESSIBLE, // Ideal inputs for RLE Compression.
	}

	public enum MatrixTypology {
		SMALL, // A Small Matrix
		LARGE, // A "Large" Matrix
		FEW_ROW, // A Matrix with a large number of rows and less columns
		FEW_COL, // A Matrix with a large number of columns
		SINGLE_ROW, // Single Row with some columns
		SINGLE_COL, // Single Column with some rows
		L_ROWS, // Many Rows
		XL_ROWS, // A LOT of rows.
		SINGLE_COL_L, // Single Column large.
	}

	public enum ValueRange {
		SMALL, LARGE, BYTE
	}

	public static double getSparsityValue(SparsityType sparsityType) {
		switch(sparsityType) {
			case DENSE:
				return sparsityValues[0];
			case SPARSE:
				return sparsityValues[1];
			case ULTRA_SPARSE:
				return sparsityValues[2];
			case EMPTY:
				return sparsityValues[3];
			case FULL:
				return sparsityValues[4];
			default:
				throw new RuntimeException("Invalid Sparsity type");
		}
	}

	public static int getMinRangeValue(ValueRange valueRange) {
		switch(valueRange) {
			case SMALL:
				return mins[0];
			case LARGE:
				return mins[1];
			case BYTE:
				return -127;
			default:
				throw new RuntimeException("Invalid range value enum type");
		}
	}

	public static int getMaxRangeValue(ValueRange valueRange) {
		switch(valueRange) {
			case SMALL:
				return maxs[0];
			case LARGE:
				return maxs[1];
			case BYTE:
				return 127;
			default:
				throw new RuntimeException("Invalid range value enum type");
		}
	}

	public static int getNumberOfRows(MatrixTypology matrixTypology) {
		switch(matrixTypology) {
			case SMALL:
				return rows[0];
			case LARGE:
				return rows[1];
			case FEW_ROW:
				return rows[2];
			case FEW_COL:
				return rows[3];
			case SINGLE_ROW:
				return rows[4];
			case SINGLE_COL:
				return rows[5];
			case L_ROWS:
				return rows[6];
			case XL_ROWS:
				return rows[7];
			case SINGLE_COL_L:
				return rows[8];
			default:
				throw new RuntimeException("Invalid matrix enum type");
		}
	}

	public static int getNumberOfColumns(MatrixTypology matrixTypology) {
		switch(matrixTypology) {
			case SMALL:
				return cols[0];
			case LARGE:
				return cols[1];
			case FEW_ROW:
				return cols[2];
			case FEW_COL:
				return cols[3];
			case SINGLE_ROW:
				return cols[4];
			case SINGLE_COL:
				return cols[5];
			case L_ROWS:
				return cols[6];
			case XL_ROWS:
				return cols[7];
			case SINGLE_COL_L:
				return cols[8];
			default:
				throw new RuntimeException("Invalid matrix enum type");
		}
	}
}
