/*
 * 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.runtime.data;

import org.apache.commons.lang.NotImplementedException;
import org.apache.sysds.runtime.DMLRuntimeException;
import org.apache.sysds.runtime.meta.DataCharacteristics;

import java.util.Arrays;
import java.util.List;

public class LibTensorReorg {
	//allow shallow dense/sparse copy for unchanged data (which is
	//safe due to copy-on-write and safe update-in-place handling)
	private static final boolean SHALLOW_COPY_REORG = true;

	private LibTensorReorg() {
		//prevent instantiation via private constructor
	}

	/**
	 * CP reshape operation (single input, single output tensor)
	 *
	 * @param in input tensor
	 * @param out output tensor
	 * @param dims dimensions
	 * @return output tensor
	 */
	public static BasicTensorBlock reshape(BasicTensorBlock in, BasicTensorBlock out, int[] dims) {
		long length = 1;
		for (int dim : dims) {
			length *= dim;
		}
		int[] inDims = in.getDims();
		//check validity
		if(in.getLength() != length) {
			throw new DMLRuntimeException("Reshape tensor requires consistent numbers of input/output cells (" +
					Arrays.toString(inDims) + ", " + Arrays.toString(dims) + ").");
		}

		//check for same dimensions
		if( Arrays.equals(inDims, dims)) {
			//copy incl dims, nnz
			if( SHALLOW_COPY_REORG )
				out.copyShallow(in);
			else // TODO deep copy
				out.copy(in);
			return out;
		}

		// TODO eval sparse output
		out._sparse = false;

		//set output dimensions
		out._dims = dims;
		out._nnz = in._nnz;

		//core reshape (sparse or dense)
		if(!in.isSparse() && !out.isSparse())
			reshapeDense(in, out, dims);
		else if(in.isSparse() && out.isSparse())
			throw new NotImplementedException();
		else if(in.isSparse())
			throw new NotImplementedException();
		else
			throw new NotImplementedException();

		return out;
	}

	private static void reshapeDense(BasicTensorBlock in, BasicTensorBlock out, int[] dims) {
		//reshape empty block
		if( in._denseBlock == null )
			return;

		//shallow dense by-row reshape (w/o result allocation)
		if( SHALLOW_COPY_REORG && in._denseBlock.numBlocks()==1 ) {
			//since the physical representation of dense matrices is always the same,
			//we don't need to create a copy, given our copy on write semantics.
			//however, note that with update in-place this would be an invalid optimization
			DenseBlock denseBlock = in._denseBlock;
			if (denseBlock instanceof DenseBlockBool) {
				DenseBlockBool specificBlock = (DenseBlockBool) denseBlock;
				out._denseBlock = DenseBlockFactory.createDenseBlock(specificBlock.getData(), dims);
			} else if (denseBlock instanceof DenseBlockString) {
				DenseBlockString specificBlock = (DenseBlockString) denseBlock;
				out._denseBlock = DenseBlockFactory.createDenseBlock(specificBlock.getData(), dims);
			}else if (denseBlock instanceof DenseBlockFP64) {
				out._denseBlock = DenseBlockFactory.createDenseBlock(in._denseBlock.valuesAt(0), dims);
			} else if (denseBlock instanceof DenseBlockFP32) {
				DenseBlockFP32 specificBlock = (DenseBlockFP32) denseBlock;
				out._denseBlock = DenseBlockFactory.createDenseBlock(specificBlock.getData(), dims);
			} else if (denseBlock instanceof DenseBlockInt64) {
				DenseBlockInt64 specificBlock = (DenseBlockInt64) denseBlock;
				out._denseBlock = DenseBlockFactory.createDenseBlock(specificBlock.getData(), dims);
			} else if (denseBlock instanceof DenseBlockInt32) {
				DenseBlockInt32 specificBlock = (DenseBlockInt32) denseBlock;
				out._denseBlock = DenseBlockFactory.createDenseBlock(specificBlock.getData(), dims);
			}
			return;
		}
		out.set(in);
	}

	/**
	 * MR/SPARK reshape interface - for reshape we cannot view blocks independently, and hence,
	 * there are different CP and MR interfaces.
	 *
	 * @param in indexed tensor block
	 * @param mcIn input tensor characteristics
	 * @param mcOut output tensor characteristics
	 * @param rowwise if true, reshape by row
	 * @param outputEmptyBlocks output blocks with nnz=0
	 * @return list of indexed tensor block
	 */
	public static List<IndexedTensorBlock> reshape(IndexedTensorBlock in, DataCharacteristics mcIn,
	                                               DataCharacteristics mcOut, boolean rowwise, boolean outputEmptyBlocks ) {
		throw new DMLRuntimeException("Spark reshape not implemented for tensors.");
	}
}
