/*
 * 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 java.util.Arrays;
import java.util.Iterator;

import org.apache.sysds.runtime.matrix.data.IJV;
import org.apache.sysds.runtime.util.SortUtils;
import org.apache.sysds.runtime.util.UtilFunctions;

/**
 * SparseBlock implementation that realizes a traditional 'coordinate matrix'
 * representation, where the entire sparse block is stored as triples in three arrays: 
 * row indexes, column indexes, and values, where row indexes and colunm indexes are
 * sorted in order to allow binary search. This format is very memory efficient for
 * ultra-sparse matrices, allows fast incremental construction but has performance
 * drawbacks for row-major access through our sparse block abstraction since there
 * is no constant-time random access to individual rows. Similar to CSR, the nnz
 * is limited to Integer.MAX_VALUE.
 * 
 * In contrast to COO matrix formats with three arrays, we use 1+#dims arrays
 * to represent the values and indexes of all dimensions.
 * 
 */
public class SparseBlockCOO extends SparseBlock 
{
	private static final long serialVersionUID = 7223478015917668745L;

	private int _rlen = -1;
	private int[] _rindexes = null;  //row index array (size: >=nnz)
	private int[] _cindexes = null;  //column index array (size: >=nnz)
	private double[] _values = null; //value array (size: >=nnz)
	private int _size = 0;           //actual number of nnz
	
	public SparseBlockCOO(int rlen) {
		this(rlen, INIT_CAPACITY);
	}
	
	public SparseBlockCOO(int rlen, int capacity) {
		_rlen = rlen;
		_rindexes = new int[capacity];
		_cindexes = new int[capacity];
		_values = new double[capacity];
		_size = 0;
	}
	
	/**
	 * Copy constructor sparse block abstraction.
	 * 
	 * @param sblock sparse block to copy
	 */
	public SparseBlockCOO(SparseBlock sblock)
	{
		long size = sblock.size();
		if( size > Integer.MAX_VALUE )
			throw new RuntimeException("SparseBlockCOO supports nnz<=Integer.MAX_VALUE but got "+size);
		
		//special case SparseBlockCSR
		if( sblock instanceof SparseBlockCOO ) { 
			SparseBlockCOO ocoo = (SparseBlockCOO)sblock;
			_rlen = ocoo._rlen;
			_rindexes = Arrays.copyOf(ocoo._rindexes, ocoo._size);
			_cindexes = Arrays.copyOf(ocoo._cindexes, ocoo._size);
			_values = Arrays.copyOf(ocoo._values, ocoo._size);
			_size = ocoo._size;
		}
		//general case SparseBlock
		else {
			_rlen = sblock.numRows();  
			_rindexes = new int[(int)size];
			_cindexes = new int[(int)size];
			_values = new double[(int)size];
			_size = (int)size;
			
			for( int i=0, pos=0; i<_rlen; i++ ) {
				if( !sblock.isEmpty(i) ) {
					int apos = sblock.pos(i);
					int alen = sblock.size(i);
					int[] aix = sblock.indexes(i);
					double[] avals = sblock.values(i);
					for( int j=apos; j<apos+alen; j++ ) {
						_rindexes[pos] = i;
						_cindexes[pos] = aix[j];
						_values[pos] = avals[j];
						pos++;
					}
				}
			}	
		}
	}
	
	/**
	 * Copy constructor old sparse row representation. 
	 * 
	 * @param rows array of sparse rows
	 * @param nnz number of non-zeros
	 */
	public SparseBlockCOO(SparseRow[] rows, int nnz)
	{
		_rlen = rows.length;
		
		_rindexes = new int[nnz];
		_cindexes = new int[nnz];
		_values = new double[nnz];
		_size = nnz;
		
		for( int i=0, pos=0; i<_rlen; i++ ) {
			int alen = rows[i].size();
			int[] aix = rows[i].indexes();
			double[] avals = rows[i].values();
			for( int j=0; j<alen; j++ ) {
				_rindexes[pos] = i;
				_cindexes[pos] = aix[j];
				_values[pos] = avals[j];
				pos++;
			}
		}
	}
		
	/**
	 * Get the estimated in-memory size of the sparse block in COO 
	 * with the given dimensions w/o accounting for overallocation. 
	 * 
	 * @param nrows number of rows
	 * @param ncols number of columns
	 * @param sparsity sparsity ratio
	 * @return memory estimate
	 */
	public static long estimateMemory(long nrows, long ncols, double sparsity) {
		double lnnz = Math.max(INIT_CAPACITY, Math.ceil(sparsity*nrows*ncols));
		
		//32B overhead per array, int/int/double arr in nnz 
		double size = 16 + 8;   //object + 2 int fields
		size += 24 + lnnz * 4d; //rindexes array (row indexes)
		size += 24 + lnnz * 4d; //cindexes array (column indexes)
		size += 24 + lnnz * 8d; //values array (non-zero values)
		
		//robustness for long overflows
		return (long) Math.min(size, Long.MAX_VALUE);
	}
	
	///////////////////
	//SparseBlock implementation
	
	@Override
	public void allocate(int r) {
		//do nothing everything preallocated
	}
	
	@Override
	public void allocate(int r, int nnz) {
		//do nothing everything preallocated
	}
	
	@Override
	public void allocate(int r, int ennz, int maxnnz) {
		//do nothing everything preallocated
	}
	
	@Override
	public void compact(int r) {
		//do nothing everything preallocated
	}

	@Override
	public int numRows() {
		return _rlen;
	}

	@Override
	public boolean isThreadSafe() {
		return false;
	}
	
	@Override
	public boolean isContiguous() {
		return true;
	}
	
	@Override
	public boolean isAllocated(int r) {
		return true;
	}

	@Override
	public boolean checkValidity(int rlen, int clen, long nnz, boolean strict) {
		//1. correct meta data
		if(rlen < 0 || clen < 0) {
			throw new RuntimeException("Invalid block dimensions: "+rlen+" "+clen);
		}

		//2. correct array lengths
		if(_size != nnz && _cindexes.length < nnz && _rindexes.length < nnz && _values.length < nnz) {
			throw new RuntimeException("Incorrect array lengths.");
		}

		//3.1. sort order of row indices
		for( int i=1; i<=nnz; i++ ) {
			if(_rindexes[i] < _rindexes[i-1])
				throw new RuntimeException("Wrong sorted order of row indices");
		}

		//3.2. sorted values wrt to col indexes wrt to a given row index
		for( int i=0; i<rlen; i++ ) {
			int apos = pos(i);
			int alen = size(i);
			for(int k=apos+i; k<apos+alen; k++)
				if( _cindexes[k+1] >= _cindexes[k] )
					throw new RuntimeException("Wrong sparse row ordering: "
							+ k + " "+_cindexes[k-1]+" "+_cindexes[k]);
			for( int k=apos; k<apos+alen; k++ )
				if(_values[k] == 0)
					throw new RuntimeException("Wrong sparse row: zero at "
							+ k + " at col index " + _cindexes[k]);
		}

		//4. non-existing zero values
		for( int i=0; i<_size; i++ ) {
			if( _values[i] == 0)
				throw new RuntimeException("The values array should not contain zeros."
						+ " The " + i + "th value is "+_values[i]);
		}

		//5. a capacity that is no larger than nnz times the resize factor
		int capacity = _values.length;
		if( capacity > nnz*RESIZE_FACTOR1 ) {
			throw new RuntimeException("Capacity is larger than the nnz times a resize factor."
					+ " Current size: "+capacity+ ", while Expected size:"+nnz*RESIZE_FACTOR1);
		}

		return true;
	}

	@Override 
	public void reset() {
		_size = 0;
	}
	
	@Override 
	public void reset(int ennz, int maxnnz) {
		_size = 0;
	}
	
	@Override 
	public void reset(int r, int ennz, int maxnnz) {
		int pos = pos(r);
		int len = size(r);
		
		if( len > 0 ) {
			//overlapping array copy (shift rhs values left)
			System.arraycopy(_rindexes, pos+len, _rindexes, pos, _size-(pos+len));
			System.arraycopy(_cindexes, pos+len, _cindexes, pos, _size-(pos+len));
			System.arraycopy(_values, pos+len, _values, pos, _size-(pos+len));
			_size -= len;
		}
	}
	
	@Override
	public long size() {
		return _size;
	}

	@Override
	public int size(int r) {
		int pos = pos(r);
		if( pos>=_size || _rindexes[pos]!=r )
			return 0;
		
		//count number of equal row indexes
		double rix0 = _rindexes[pos];
		int cnt = 0;
		while( pos<_size && rix0 == _rindexes[pos++] )
			cnt ++;
		return cnt;
	}
	
	@Override
	public long size(int rl, int ru) {
		return pos(ru) - pos(rl);
	}
	
	@Override
	public long size(int rl, int ru, int cl, int cu) {
		long nnz = 0;
		for(int i=rl; i<ru; i++)
			if( !isEmpty(i) ) {
				int start = internPosFIndexGTE(i, cl);
				int end = internPosFIndexGTE(i, cu);
				nnz += (start!=-1) ? (end-start) : 0;
			}
		return nnz;
	}

	@Override
	public boolean isEmpty(int r) {
		int pos = pos(r);
		return (pos>=_size||_rindexes[pos]!=r);
	}
	
	@Override
	public int[] indexes(int r) {
		return _cindexes;
	}

	@Override
	public double[] values(int r) {
		return _values;
	}

	@Override
	public int pos(int r) {
		//find row index partition
		int index = Arrays.binarySearch(_rindexes, 0, _size, r);
		if( index < 0 )
			return Math.abs(index+1);
			
		//scan to begin of row index partition
		while( index>0 && _rindexes[index-1]==r )
			index--;
		return index;
	}

	@Override
	public boolean set(int r, int c, double v) {
		int pos = pos(r);
		int len = size(r);
		
		//search for existing col index
		int index = Arrays.binarySearch(_cindexes, pos, pos+len, c);
			
		if( index >= 0 ) {
			//delete/overwrite existing value (on value delete, we shift 
			//left for (1) correct nnz maintenance, and (2) smaller size)
			if( v == 0 ) {
				shiftLeftAndDelete(index);
				return true; // nnz--
			}
			else {
				_values[index] = v;
				return false;
			} 
		}
		
		//early abort on zero (if no overwrite)
		if( v==0 ) return false;
		
		//insert new index-value pair
		index = Math.abs( index+1 );
		if( _size==_values.length )
			resizeAndInsert(index, r, c, v);
		else
			shiftRightAndInsert(index, r, c, v);
		return true; // nnz++
	}
	
	@Override
	public void set(int r, SparseRow row, boolean deep) {
		int pos = pos(r);
		int alen = row.size();
		int[] aix = row.indexes();
		double[] avals = row.values();
		//delete existing values in range if necessary 
		deleteIndexRange(r, aix[0], aix[alen-1]+1);
		//prepare free space (allocate and shift)
		int lsize = _size+alen;
		if( _values.length < lsize )
			resize(lsize);
		shiftRightByN(pos, alen);
		Arrays.fill(_rindexes, pos, pos+alen, r);
		System.arraycopy(aix, 0, _cindexes, pos, alen);
		System.arraycopy(avals, 0, _values, pos, alen);
	}
	
	@Override
	public boolean add(int r, int c, double v) {
		return set(r, c, get(r, c) + v);
	}

	@Override
	public void append(int r, int c, double v) {
		//early abort on zero 
		if( v==0 ) return;
	
		if( _size==_values.length ) 
			resize();
		insert(_size, r, c, v);
	}

	@Override
	public void setIndexRange(int r, int cl, int cu, double[] v, int vix, int vlen) {
		//delete existing values in range if necessary
		deleteIndexRange(r, cl, cu);
		
		//determine input nnz
		int lnnz = UtilFunctions.computeNnz(v, vix, vlen);
		
		//prepare free space (allocate and shift)
		int lsize = _size+lnnz;
		if( _values.length < lsize )
			resize(lsize);
		int index = internPosFIndexGT(r, cl);
		shiftRightByN((index>0)?index:pos(r+1), lnnz);
		
		//insert values
		for( int i=vix; i<vix+vlen; i++ )
			if( v[i] != 0 ) {
				_rindexes[ index ] = r;
				_cindexes[ index ] = cl+i-vix;
				_values[ index ] = v[i];
				index++;
			}
	}
	
	@Override
	public void setIndexRange(int r, int cl, int cu, double[] v, int[] vix, int vpos, int vlen) {
		//delete existing values in range if necessary
		deleteIndexRange(r, cl, cu);
		
		//prepare free space (allocate and shift)
		int lsize = _size+vlen;
		if( _values.length < lsize )
			resize(lsize);
		int index = internPosFIndexGT(r, cl);
		shiftRightByN((index>0)?index:pos(r+1), vlen);
		
		//insert values
		for( int i=vpos; i<vpos+vlen; i++ ) {
			_rindexes[ index ] = r;
			_cindexes[ index ] = cl+vix[i];
			_values[ index ] = v[i];
			index++;
		}
	}

	@Override
	public void deleteIndexRange(int r, int cl, int cu) {
		int start = internPosFIndexGTE(r,cl);
		if( start < 0 ) //nothing to delete 
			return;

		int len = size(r);
		int end = internPosFIndexGTE(r, cu);
		if( end < 0 ) //delete all remaining
			end = start+len;
		
		//overlapping array copy (shift rhs values left)
		System.arraycopy(_rindexes, end, _rindexes, start, _size-end);
		System.arraycopy(_cindexes, end, _cindexes, start, _size-end);
		System.arraycopy(_values, end, _values, start, _size-end);
		_size -= (end-start);
	}

	@Override
	public void sort() {
		//sort all three indexes by _rindexes
		SortUtils.sortByIndex(0, _size, _rindexes, _cindexes, _values);
		
		//sort _cindexes/_values by _cindexes per row partition
		int index = 0;
		while( index < _size ) {
			int r = _rindexes[index];
			int len = 0;
			while( index < _size && r == _rindexes[index] ) {
				len ++;
				index ++;
			}
			SortUtils.sortByIndex(index-len, index, _cindexes, _values);
		}
	}

	@Override
	public void sort(int r) {
		int pos = pos(r);
		int len = size(r);
		
		if( len<=100 || !SortUtils.isSorted(pos, pos+len, _cindexes) )
			SortUtils.sortByIndex(pos, pos+len, _cindexes, _values);
	}

	@Override
	public double get(int r, int c) {
		int pos = pos(r);
		int len = size(r);
		
		//search for existing col index in [pos,pos+len)
		int index = Arrays.binarySearch(_cindexes, pos, pos+len, c);
		return (index >= 0) ? _values[index] : 0;
	}
	
	@Override 
	public SparseRow get(int r) {
		int pos = pos(r);
		int len = size(r);
		
		SparseRowVector row = new SparseRowVector(len);
		System.arraycopy(_cindexes, pos, row.indexes(), 0, len);
		System.arraycopy(_values, pos, row.values(), 0, len);
		row.setSize(len);
		
		return row;
	}

	@Override
	public int posFIndexLTE(int r, int c) {
		int index = internPosFIndexLTE(r, c);
		return (index>=0) ? index-pos(r) : index;
	}
	
	private int internPosFIndexLTE(int r, int c) {
		int pos = pos(r);
		int len = size(r);
		
		//search for existing col index in [pos,pos+len)
		int index = Arrays.binarySearch(_cindexes, pos, pos+len, c);
		if( index >= 0  )
			return (index < pos+len) ? index : -1;
		
		//search lt col index (see binary search)
		index = Math.abs( index+1 );
		return (index-1 >= pos) ? index-1 : -1;
	}

	@Override
	public int posFIndexGTE(int r, int c) {
		int index = internPosFIndexGTE(r, c);
		return (index>=0) ? index-pos(r) : index;
	}
	
	private int internPosFIndexGTE(int r, int c) {
		int pos = pos(r);
		int len = size(r);
		
		//search for existing col index
		int index = Arrays.binarySearch(_cindexes, pos, pos+len, c);
		if( index >= 0  )
			return (index < pos+len) ? index : -1;
		
		//search gt col index (see binary search)
		index = Math.abs( index+1 );
		return (index < pos+len) ? index : -1;
	}

	@Override
	public int posFIndexGT(int r, int c) {
		int index = internPosFIndexGT(r, c);
		return (index>=0) ? index-pos(r) : index;
	}
	
	private int internPosFIndexGT(int r, int c) {
		int pos = pos(r);
		int len = size(r);
		
		//search for existing col index
		int index = Arrays.binarySearch(_cindexes, pos, pos+len, c);
		if( index >= 0  )
			return (index+1 < pos+len) ? index+1 : -1;
		
		//search gt col index (see binary search)
		index = Math.abs( index+1 );
		return (index < pos+len) ? index : -1;
	}

	@Override
	public Iterator<IJV> getIterator() {
		return new SparseBlockCOOIterator(0, _size);
	}
	
	@Override
	public Iterator<IJV> getIterator(int ru) {
		return new SparseBlockCOOIterator(0, pos(ru));
	}

	@Override
	public Iterator<IJV> getIterator(int rl, int ru) {
		return new SparseBlockCOOIterator(pos(rl), pos(ru));
	}

	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder();
		sb.append("SparseBlockCOO: rlen=");
		sb.append(_rlen);
		sb.append(", nnz=");
		sb.append(_size);
		sb.append("\n");
		for( int i=0; i<_size; i++ ) {
			sb.append(_rindexes[i]);
			sb.append(",");
			sb.append(_cindexes[i]);
			sb.append(":");
			sb.append(_values[i]);
			sb.append("\n");
		}		
		return sb.toString();
	}
	
	///////////////////////////
	// private helper methods

	private void resize() {
		//compute new size
		double tmpCap = Math.ceil(_values.length * RESIZE_FACTOR1);
		int newCap = (int)Math.min(tmpCap, Integer.MAX_VALUE);
		
		resize(newCap);
	}

	private void resize(int capacity) {
		//reallocate arrays and copy old values
		_rindexes = Arrays.copyOf(_rindexes, capacity);
		_cindexes = Arrays.copyOf(_cindexes, capacity);
		_values = Arrays.copyOf(_values, capacity);
	}

	private void resizeAndInsert(int ix, int r, int c, double v) {
		//compute new size
		double tmpCap = Math.ceil(_values.length * RESIZE_FACTOR1);
		int newCap = (int)Math.min(tmpCap, Integer.MAX_VALUE);
		
		int[] oldrindexes = _rindexes;
		int[] oldcindexes = _cindexes;
		double[] oldvalues = _values;
		_rindexes = new int[newCap];
		_cindexes = new int[newCap];
		_values = new double[newCap];
		
		//copy lhs values to new array
		System.arraycopy(oldrindexes, 0, _rindexes, 0, ix);
		System.arraycopy(oldcindexes, 0, _cindexes, 0, ix);
		System.arraycopy(oldvalues, 0, _values, 0, ix);
		
		//copy rhs values to new array
		System.arraycopy(oldrindexes, ix, _rindexes, ix+1, _size-ix);
		System.arraycopy(oldcindexes, ix, _cindexes, ix+1, _size-ix);
		System.arraycopy(oldvalues, ix, _values, ix+1, _size-ix);
		
		//insert new value
		insert(ix, r, c, v);
	}

	private void shiftRightAndInsert(int ix, int r, int c, double v) {
		//overlapping array copy (shift rhs values right by 1)
		System.arraycopy(_rindexes, ix, _rindexes, ix+1, _size-ix);
		System.arraycopy(_cindexes, ix, _cindexes, ix+1, _size-ix);
		System.arraycopy(_values, ix, _values, ix+1, _size-ix);
		
		//insert new value
		insert(ix, r, c, v);
	}

	private void shiftLeftAndDelete(int ix)
	{
		//overlapping array copy (shift rhs values left by 1)
		System.arraycopy(_rindexes, ix+1, _rindexes, ix, _size-ix-1);
		System.arraycopy(_cindexes, ix+1, _cindexes, ix, _size-ix-1);
		System.arraycopy(_values, ix+1, _values, ix, _size-ix-1);
		_size--;
	}

	private void shiftRightByN(int ix, int n) {
		//overlapping array copy (shift rhs values right by 1)
		System.arraycopy(_rindexes, ix, _rindexes, ix+n, _size-ix);
		System.arraycopy(_cindexes, ix, _cindexes, ix+n, _size-ix);
		System.arraycopy(_values, ix, _values, ix+n, _size-ix);
		_size += n;
	}

	private void insert(int ix, int r, int c, double v) {
		_rindexes[ix] = r;
		_cindexes[ix] = c;
		_values[ix] = v;
		_size++;
	}
	
	/**
	 * Custom sparse block COO iterator implemented against the 
	 * SparseBlockCOO data structure in order to avoid unnecessary
	 * binary search for row locations and lengths.
	 * 
	 */
	private class SparseBlockCOOIterator implements Iterator<IJV>
	{
		private int _pos = 0; //current nnz position
		private int _len = 0; //upper nnz position (exclusive)
		private IJV retijv = new IJV(); //reuse output tuple

		protected SparseBlockCOOIterator(int posrl, int posru) {
			_pos = posrl;
			_len = posru;
		}
		
		@Override
		public boolean hasNext() {
			return _pos<_len;
		}

		@Override
		public IJV next( ) {
			retijv.set(_rindexes[_pos], _cindexes[_pos], _values[_pos++]);			
			return retijv;
		}

		@Override
		public void remove() {
			throw new RuntimeException("SparseBlockCOOIterator is unsupported!");			
		}		
	}
	
	/**
	 * Get raw access to underlying array of row indices
	 * For use in GPU code
	 * @return array of row indices
	 */
	public int[] rowIndexes() {
		return _rindexes;
	}
	
	/** 
	 * Get raw access to underlying array of column indices
	 * For use in GPU code
	 * @return array of column indices
	 */
	public int[] indexes() {
		return _cindexes;
	}
	
	/**
	 * Get raw access to underlying array of values
	 * For use in GPU code
	 * @return array of values
	 */
	public double[] values() {
		return _values;
	}
}
