/**
 * 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.ranger.authorization.hadoop.utils;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.lang.reflect.Field;
import java.util.List;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.security.alias.CredentialProvider;
import org.apache.hadoop.security.alias.CredentialShell;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class RangerCredentialProviderTest {
	
	private final File ksFile =  new File(System.getProperty("user.home")+"/testkeystore.jceks") ;
	private final String keystoreFile = ksFile.toURI().getPath();
	private String[] argsCreate = {"create", "TestCredential001", "-value", "PassworD123", "-provider", "jceks://file@/" + keystoreFile};
	private String[] argsDelete = {"delete", "TestCredential001", "-provider", "jceks://file@/" + keystoreFile};
	private String url = "jceks://file@/" + keystoreFile;
	RangerCredentialProvider cp = null;
	List<CredentialProvider> providers = null;
	
	
	public RangerCredentialProviderTest() {
		if ( isCredentialShellInteractiveEnabled() ) {
			argsCreate = new String[] {"create", "TestCredential001", "-f",  "-value", "PassworD123", "-provider", "jceks://file@/" + keystoreFile};
			argsDelete = new String[] {"delete", "TestCredential001", "-f" , "-provider", "jceks://file@/" + keystoreFile};
		}
	}
	
	
	@Before
	public void setup() throws Exception {
		int ret;
		//
		// adding a delete before creating a keystore
		//
		try {
			if (ksFile != null) {
				if (ksFile.exists()) {
					System.out.println("Keystore File [" + ksFile.getAbsolutePath() + "] is available - and deleting") ;
					ksFile.delete() ;
					System.out.println("Keystore File [" + ksFile.getAbsolutePath() + "] is deleted.") ;
				}
				else {
					System.out.println("Keystore File [" + ksFile.getAbsolutePath() + "] is not available") ;
				}
			}
			else {
				System.out.println("Keystore File is NULL") ;
			}
		}
		catch(Throwable t) {
			t.printStackTrace();
		}
		
		Configuration conf = new Configuration();
		CredentialShell cs = new CredentialShell();
		cs.setConf(conf);
		try {
			 ret =cs.run(argsCreate);
		} catch (Exception e) {
			throw e;
		}
		finally {
		}
		assertEquals(0,ret);
		System.out.println("(1) Number of active Threads : " + Thread.activeCount() ) ;
		listThreads() ;
	} 
	
	@Test
	public void testCredentialProvider() {
		//test credential provider is registered and return credential providers.
		cp = new RangerCredentialProvider();
		providers = cp.getCredentialProviders(url);
		if (providers != null) {
			assertTrue(url.equals(providers.get(0).toString()));
		}
		System.out.println("(2) Number of active Threads : " + Thread.activeCount() ) ;
		listThreads() ;
	}
	
	@Test
	public void testCredentialString() {
		//test credential provider created is returning the correct credential string.
		cp = new RangerCredentialProvider();
		providers = cp.getCredentialProviders(url);
		if (providers != null) {
			assertTrue("PassworD123".equals(new String(cp.getCredentialString(url,"TestCredential001"))));
		}
		System.out.println("(3) Number of active Threads : " + Thread.activeCount() ) ;
		listThreads() ;
	}

	
	@After
	public void teardown() throws Exception {
		System.out.println("In teardown : Number of active Threads : " + Thread.activeCount() ) ;
		int ret;
		Configuration conf = new Configuration();
		CredentialShell cs = new CredentialShell();
		cs.setConf(conf);
		try {
			 ret =cs.run(argsDelete);
		} catch (Exception e) {
			throw e;
		}
		assertEquals(0,ret);	
		listThreads() ;
	}
	
	private static void 		listThreads() {
		int ac = Thread.activeCount() ;
		if (ac > 0) {
			Thread[] tlist = new Thread[ac] ;
			Thread.enumerate(tlist) ;
			for(Thread t : tlist) {
				System.out.println("Thread [" + t + "] => {" + t.getClass().getName() + "}") ;
			}
		}
	}
	
	private static boolean isCredentialShellInteractiveEnabled() {
		boolean ret = false ;
		
		String fieldName = "interactive" ;
		
		CredentialShell cs = new CredentialShell() ;
		
		try {
			Field interactiveField = cs.getClass().getDeclaredField(fieldName) ;
			
			if (interactiveField != null) {
				interactiveField.setAccessible(true);
				ret = interactiveField.getBoolean(cs) ;
				System.out.println("FOUND value of [" + fieldName + "] field in the Class [" + cs.getClass().getName() + "] = [" + ret + "]") ;
			}
		} catch (Throwable e) {
			System.out.println("Unable to find the value of [" + fieldName + "] field in the Class [" + cs.getClass().getName() + "]. Skiping -f option") ;
			e.printStackTrace();
			ret = false;
		}
		
		return ret ;
		
		
	}

}

