package in.gov.digilocker.uidai.web.controller.v1;

import java.net.InetAddress;
import java.util.Date;

import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import in.gov.digilocker.uidai.logs.modal.DemoAuth;
import in.gov.digilocker.uidai.logs.sender.MessageSendTaskExecutor;
import in.gov.digilocker.uidai.services.client.DemoAuthClient;
import in.gov.digilocker.uidai.services.xmlresponse.AuthResponse;
import in.gov.digilocker.uidai.web.exceptions.KeyMismatchException;
import in.gov.digilocker.uidai.web.properties.DigilockerProperties;
import in.gov.digilocker.uidai.web.validator.Validator;

@RestController
@RequestMapping({ "/api" })
public class DemoAuthController1 {

	@Autowired Validator validator;
	@Autowired DigilockerProperties properties;
	@Autowired DemoAuthClient demoAuthClient;
	@Autowired MessageSendTaskExecutor taskExecutor;

	private static final Logger logger = LoggerFactory.getLogger(DemoAuthController1.class);

	@SuppressWarnings("deprecation")
	@PostMapping(value = { "/getdemoauth" }, produces = { "application/json;charset=UTF-8" })
	public ResponseEntity<String> demoAuthPost(@RequestParam(name = "uid", required = true) final String uid,
			@RequestParam(name = "fullname", required = true) final String personName,
			@RequestParam(name = "gender", required = true) final String personGender,
			@RequestParam(name = "dob", required = true) final String personDob,
			@RequestParam(name = "phone", required = false) final String phone,
			@RequestParam(name = "pin", required = false) final String pincode,
			@RequestParam(name = "aadhaar_token", required = true) final String token,
			@RequestParam(name = "transaction_id", required = false) String uniquereqid,
			@RequestParam(name = "consent", required = false, defaultValue = "N") String consent,
			@RequestParam(name = "type", required = false, defaultValue = "A") final String type,
			@RequestParam(name = "authtype", required = false, defaultValue = "demoauth") String authtype,
			@RequestParam(name = "key", required = false, defaultValue = "TEST") final String clientkey) {
		
		String[] infoArray = null;
		String uidToken = "";
		String reqTimeStamp = "";
		double reqTime = 0.0;
		double resTime = 0.0;
		final DemoAuth demoAuth = new DemoAuth();
		String serverIP = "";
		try {
			
			serverIP = InetAddress.getLocalHost().getHostAddress();
			reqTimeStamp = this.validator.getCurrentDateTimeISOFormat();
			authtype = this.validator.setAuthTypeForDemoAuth(authtype);
			consent = this.validator.setResidentialConsent(consent);
			uniquereqid = this.validator.generateTransactionId(uniquereqid, uid, authtype);
			this.validator.validateToken(token);
			this.validator.validateUID(uid, type);
			this.validator.validatePersonName(personName);
			this.validator.validatePersonGender(personGender);
			this.validator.validatePersonDOB(personDob);
			
			if (!"TEST".equals(clientkey)) {
				throw new KeyMismatchException("Invalid API key.");
			}
			
			demoAuth.setUniqueReqId(uniquereqid);
			demoAuth.setAadhaarNumber(uid);
			demoAuth.setFullname(personName);
			demoAuth.setGender(personGender);
			demoAuth.setDob(personDob);
			demoAuth.setPhone((phone != null && !"".equals(phone)) ? phone : "");
			demoAuth.setPin((pincode != null && !"".equals(pincode)) ? pincode : "");
			demoAuth.setType(type);
			demoAuth.setAuthType(authtype);
			demoAuth.setConsent(consent);
			demoAuth.setServerIP(serverIP);
			
			reqTime = (double) System.currentTimeMillis();
			AuthResponse demoAuthRes = this.demoAuthClient.validateDetailsUsingDemographicDetails(demoAuth, reqTimeStamp);
			resTime = (double) System.currentTimeMillis();
			String msg = "";
			boolean status = false;
			infoArray = (String[]) ((demoAuthRes != null && !"".equalsIgnoreCase(demoAuthRes.getInfo())) ? demoAuthRes.getInfo().split(",") : null);
			uidToken = ((infoArray != null) ? infoArray[0].substring(3, infoArray[0].length()).trim() : "");
			demoAuth.setAvgResTime((resTime - reqTime) / 1000.0);
			demoAuth.setUidToken(uidToken);
			
			JSONObject jsonObject = new JSONObject();	
			
			if (demoAuthRes != null && "y".equalsIgnoreCase(demoAuthRes.getRet())) {
				status = true;
				msg = "Your Authentication is Successful.";
				demoAuth.setErrCode(demoAuthRes.getErr());
				demoAuth.setErrMsg("");
				demoAuth.setStatus(status);
				demoAuth.setResponse("");
				jsonObject.put("uid_token", (Object) uidToken);
				jsonObject.put("code", (Object) "");
				jsonObject.put("status", status);
				jsonObject.put("transaction_id", (Object) uniquereqid);
				jsonObject.put("access_token", (Object) token);
				jsonObject.put("msg", (Object) msg);
				if (this.properties.isMsgqueueEnabled()) {
					this.taskExecutor.executeTask(demoAuth.toJSONObject(), "C", "demo_auth_logs", "logs"); 
				}
				return new ResponseEntity<>(jsonObject.toString(), HttpStatus.OK);
			}
			status = false;
			msg = "Your Authentication Failed.";
			
			demoAuth.setErrCode(demoAuthRes.getErr());
			demoAuth.setErrMsg(msg);
			demoAuth.setStatus(status);
			demoAuth.setResponse(demoAuthRes.getXmlResp());
			
			jsonObject.put("uid_token", (Object) uidToken);
			jsonObject.put("code", (Object) demoAuthRes.getErr());
			jsonObject.put("status", status);
			jsonObject.put("transaction_id", (Object) uniquereqid);
			jsonObject.put("access_token", (Object) token);
			jsonObject.put("msg", (Object) msg);
			
			if (this.properties.isMsgqueueEnabled()) {
				this.taskExecutor.executeTask(demoAuth.toJSONObject(), "C", "demo_auth_logs", "logs");
			}
			return new ResponseEntity<>(jsonObject.toString(), HttpStatus.EXPECTATION_FAILED);
		} catch (RuntimeException e) {
			
			DemoAuthController1.logger.error("Runtime Exception in demo auth home:- " + e.getLocalizedMessage());
			final JSONObject jsonObject2 = new JSONObject();
			jsonObject2.put("uid_token", (Object) "");
			jsonObject2.put("code", (Object) "");
			jsonObject2.put("status", false);
			jsonObject2.put("transaction_id", (Object) uniquereqid);
			jsonObject2.put("access_token", (Object) token);
			jsonObject2.put("msg", (Object) e.getMessage());
			demoAuth.setUniqueReqId((uniquereqid != null && !"".equals(uniquereqid)) ? uniquereqid : "");
			demoAuth.setUidToken("");
			demoAuth.setAadhaarNumber(uid);
			demoAuth.setFullname(personName);
			demoAuth.setGender(personGender);
			demoAuth.setDob(personDob);
			demoAuth.setPhone((phone != null && !"".equals(phone)) ? phone : "");
			demoAuth.setPin((pincode != null && !"".equals(pincode)) ? pincode : "");
			demoAuth.setType(type);
			demoAuth.setAuthType(authtype);
			demoAuth.setConsent(consent);
			demoAuth.setAvgResTime(0.0);
			demoAuth.setErrCode("RUNTIME EXCEPTION");
			demoAuth.setErrMsg(e.getLocalizedMessage());
			demoAuth.setStatus(false);
			demoAuth.setResponse("");
			
			if (this.properties.isMsgqueueEnabled()) {
				this.taskExecutor.executeTask(demoAuth.toJSONObject(), "C", "demo_auth_logs", "logs");
			}
			
			return new ResponseEntity<>(jsonObject2.toString(), HttpStatus.METHOD_FAILURE);
		} catch (Exception e2) {
			DemoAuthController1.logger.error("MAIN Exception in demo auth home:- " + e2.getLocalizedMessage());
			final JSONObject jsonObject2 = new JSONObject();
			jsonObject2.put("uid_token", (Object) "");
			jsonObject2.put("code", (Object) "");
			jsonObject2.put("status", false);
			jsonObject2.put("transaction_id", (Object) uniquereqid);
			jsonObject2.put("access_token", (Object) token);
			jsonObject2.put("msg", (Object) e2.getMessage());
			demoAuth.setUniqueReqId((uniquereqid != null && !"".equals(uniquereqid)) ? uniquereqid : "");
			demoAuth.setUidToken("");
			demoAuth.setAadhaarNumber(uid);
			demoAuth.setFullname(personName);
			demoAuth.setGender(personGender);
			demoAuth.setDob(personDob);
			demoAuth.setPhone((phone != null && !"".equals(phone)) ? phone : "");
			demoAuth.setPin((pincode != null && !"".equals(pincode)) ? pincode : "");
			demoAuth.setType(type);
			demoAuth.setAuthType(authtype);
			demoAuth.setConsent(consent);
			demoAuth.setAvgResTime(0.0);
			demoAuth.setErrCode("MAIN EXCEPTION");
			demoAuth.setErrMsg(e2.getLocalizedMessage());
			demoAuth.setStatus(false);
			demoAuth.setResponse("");
			
			if (this.properties.isMsgqueueEnabled()) {
				this.taskExecutor.executeTask(demoAuth.toJSONObject(), "C", "demo_auth_logs", "logs");
			}
			
			return new ResponseEntity<>(jsonObject2.toString(), HttpStatus.METHOD_FAILURE);
		}
	}

	@GetMapping(value = { "/getdemoauth" }, produces = { "application/json;charset=UTF-8" })
	public String getAuth() {
		final JSONObject jsonObject = new JSONObject();
		try {
			jsonObject.put("code", -1);
			jsonObject.put("status", false);
			jsonObject.put("response", (Object) "Get method not allowed here.");
			jsonObject.put("date", (Object) new Date());
		} catch (JSONException e) {
			DemoAuthController1.logger.error("Exception auth home:- " + e.getLocalizedMessage());
			jsonObject.put("code", -1);
			jsonObject.put("status", false);
			jsonObject.put("response", (Object) e.getLocalizedMessage());
			jsonObject.put("date", (Object) new Date());
		}
		return jsonObject.toString();
	}
}