import java.util.Arrays;

public class RecursiveExercise {

	// return an array that has all data of ht and n,
	// just like concatenating ht and n.
	public static int[] append(int[] ht, int[] n) throws Exception {
		if (ht == null)
			return n;
		if (n == null)
			return ht;
		int[] l = append(MyArrayUtil.tail(ht), n);
		int head = MyArrayUtil.head(ht);
		return MyArrayUtil.addAsFirst(head, l);
	}

	public static int[] reverse(int[] ht) throws Exception {
		// fill your code here
		if (ht == null)
			return null;
		if (ht.length == 1)
			return ht.clone();
		return append(new int[] { ht[ht.length - 1] },
				append(reverse(MyArrayUtil.tail(removeLast(ht.clone(), new int[ht.length - 1], 0))), new int[] { ht[0] }));
	}

	// Remove the last element
	
	public static int[] removeLast(int[] ia1, int[] ia2, int i) {
		ia2[i] = ia1[i];
		if (i == ia2.length - 1)
			return ia2;
		return removeLast(ia1, ia2, i + 1);
	}

	public static boolean isIn(int x, int[] a) throws Exception {
		// fill your code here
		if (a[0] == x)
			return true;
		if (a.length == 1)
			return false;
		return isIn(x, MyArrayUtil.tail(a.clone()));
	}

	public static boolean subArray(int[] a1, int[] a2) throws Exception {
		// fill your code here
		if (a1 == null)
			return true;
		if (isIn(a1[0], a2))
			return subArray(MyArrayUtil.tail(a1.clone()), a2);
		if (a1.length == 1)
			return true;
		return false;
	}

	public static int[] shift(int[] ht, int n) throws Exception {
		// fill your code here
		if (ht == null)
			return null;
		if (n == 0)
			return ht;
		int temp = ht[0];
		ht = reverse(MyArrayUtil.addAsFirst(temp, reverse(MyArrayUtil.tail(ht))));
		return shift(ht, n - 1);
	}

	public static void main(String[] args) throws Exception {
		// test append, when appending empty array with {1,2,3}
		int[] a = null;
		int[] b = { 1, 2, 3 };
		int[] ans1 = append(a, b);
		System.out.println("Append - Expected: 1, 2, 3.");
		System.out.print("Get: ");
		MyArrayUtil.print(ans1);
		System.out.println("");

		// test append, when appending 2 non-empty arrays.
		int[] c = { 1, 2, 3 };
		int[] d = { 4, 5, 6 };
		ans1 = append(c, d);
		System.out.println("Append - Expected: 1, 2, 3, 4, 5, 6.");
		System.out.print("Get: ");
		MyArrayUtil.print(ans1);
		System.out.println("");

		// test reverse
		int[] e = { 1, 2, 3, 4, 5 };
		ans1 = reverse(e);
		System.out.println("Reverse - Expected: 5, 4, 3, 2, 1.");
		System.out.print("Get: ");
		MyArrayUtil.print(ans1);
		System.out.println("");

		// test isIn
		boolean b1 = isIn(3, e);
		System.out.println("isIn - Expected: true.");
		System.out.println("Get: " + b1 + ".");

		boolean b2 = isIn(7, e);
		System.out.println("isIn - Expected: false.");
		System.out.println("Get: " + b2 + ".");

		// test subArray
		int[] f = { 1, 3, 5 };
		int[] g = { 1, 2, 3, 4, 5 };
		int[] h = { 1, 2, 3, 4, 5 };
		int[] i = null;
		int[] j = { 1, 4, 5 };

		b1 = subArray(f, g);
		System.out.println("subArray - Expected: true.");
		System.out.println("Get: " + b1 + ".");

		b1 = subArray(g, h);
		System.out.println("subArray - Expected: true.");
		System.out.println("Get: " + b1 + ".");

		b1 = subArray(i, h);
		System.out.println("subArray - Expected: true.");
		System.out.println("Get: " + b1 + ".");

		b1 = subArray(f, j);
		System.out.println("subArray - Expected: false.");
		System.out.println("Get: " + b1 + ".");

		b1 = subArray(h, j);
		System.out.println("subArray - Expected: false.");
		System.out.println("Get: " + b1 + ".");

		// test shift
		int[] k = shift(g, 3);
		System.out.println("shift - Expected: 4, 5, 1, 2, 3.");
		System.out.print("Get: ");
		MyArrayUtil.print(k);
		System.out.println("");

		k = shift(g, 2);
		System.out.println("shift - Expected: 3, 4, 5, 1, 2.");
		System.out.print("Get: ");
		MyArrayUtil.print(k);
		System.out.println("");

		k = shift(g, 8);
		System.out.println("shift - Expected: 4, 5, 1, 2, 3.");
		System.out.print("Get: ");
		MyArrayUtil.print(k);
		System.out.println("");

		k = shift(g, 0);
		System.out.println("shift - Expected: 1, 2, 3, 4, 5.");
		System.out.print("Get: ");
		MyArrayUtil.print(k);
		System.out.println("");

		k = shift(null, 5);
		System.out.println("shift - Expected: Array empty");
		System.out.print("Get: ");
		MyArrayUtil.print(k);
		System.out.println("");
	}

}
