/*
 * Copyright 2018 Scytl Secure Electronic Voting SA
 *
 * All rights reserved
 *
 * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package
 */
package com.scytl.products.ov.vw.infrastructure.log;

import java.util.regex.Pattern;

import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.json.JsonException;
import javax.json.JsonObject;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.scytl.cryptolib.api.exceptions.GeneralCryptoLibException;
import com.scytl.products.ov.commons.beans.domain.model.vote.Vote;
import com.scytl.products.ov.commons.logging.service.AuthTokenHashService;
import com.scytl.products.ov.commons.logging.service.VoteHashService;
import com.scytl.products.ov.commons.util.JsonUtils;
import com.scytl.products.ov.vw.services.domain.model.authentication.AuthenticationToken;
import com.scytl.products.ov.vw.services.domain.model.confirmation.ConfirmationInformation;

/**
 * Stores data for secure logging purposes.
 */
@RequestScoped
public class SecureLoggerInformation {
    private static final Pattern ID_PATTERN = Pattern.compile("[a-zA-Z0-9\\=]*");

    private AuthenticationToken authenticationTokenObject;

    private String authenticationToken;

    private Vote vote;

    private ConfirmationInformation confirmationInformation;

    private static final Logger LOG = LoggerFactory.getLogger("std");

    @Inject
    private AuthTokenHashService authTokenHashService;

    @Inject
    private VoteHashService voteHashService;

    @Inject
    private ConfirmationMessageHashService confirmationMessageHashService;

    /**
     * Sets the value of the field authenticationToken.
     *
     * @param authenticationToken
     *            The authenticationToken to set.
     */
    public void setAuthenticationToken(String authenticationToken) {
        this.authenticationToken = authenticationToken;
    }

    /**
     * Sets the value of the field vote.
     *
     * @param vote
     *            The vote to set.
     */
    public void setVote(Vote vote) {
        this.vote = vote;
    }

    /**
     * Returns the current value of the field authenticationToken.
     *
     * @return Returns the authenticationToken.
     */
    public String getAuthenticationToken() {
        return authenticationToken;
    }

    /**
     * Returns the current value of the field vote.
     *
     * @return Returns the vote.
     */
    public Vote getVote() {
        return vote;
    }

    /**
     * Returns the current value of the field confirmationInformation.
     *
     * @return Returns the confirmationMessage.
     */
    public ConfirmationInformation getConfirmationInformation() {
        return confirmationInformation;
    }

    /**
     * Sets the value of the field confirmationInformation.
     *
     * @param confirmationInformation
     *            The confirmationInformation to set.
     */
    public void setConfirmationInformation(ConfirmationInformation confirmationInformation) {
        this.confirmationInformation = confirmationInformation;
    }

    /**
     * Returns the current value of the field authenticationTokenObject.
     *
     * @return Returns the authenticationTokenObject.
     */
    public AuthenticationToken getAuthenticationTokenObject() {
        return authenticationTokenObject;
    }

    /**
     * Sets the value of the field authenticationTokenObject.
     *
     * @param authenticationTokenObject
     *            The authenticationTokenObject to set.
     */
    public void setAuthenticationTokenObject(AuthenticationToken authenticationTokenObject) {
        this.authenticationTokenObject = authenticationTokenObject;
    }

    /**
     * Returns the auth token hash.
     * 
     * @return hash of the auth token.
     */
    public String getAuthenticationTokenHash() {
        String authTokenHash = "";
        if (authenticationToken != null) {
            try {
                JsonObject authTokenJsonObject = JsonUtils.getJsonObject(authenticationToken);
                authTokenHash = authTokenHashService.hash(authTokenJsonObject);
            } catch (JsonException | IllegalStateException | GeneralCryptoLibException e) {
                // error creating auth token hash
                LOG.error("Error generating auth token hash for secure logging", e);
            }
        }
        return authTokenHash;
    }

    /**
     * Returns the sanitized authentication token identifier.
     * 
     * @return the identifier.
     */
    public String getAuthenticationTokenId() {
        String id = authenticationTokenObject != null ? authenticationTokenObject.getId() : null;
        return sanitize(id, ID_PATTERN);
    }

    /**
     * Returns the vote hash.
     * 
     * @return hash of the vote.
     */
    public String getVoteHash() {
        String voteHash = "";
        if (vote != null) {
            try {
                voteHash = voteHashService.hash(vote);
            } catch (JsonException | IllegalStateException | GeneralCryptoLibException e) {
                // error creating vote hash
                LOG.error("Error generating vote hash for secure logging", e);
            }
        }
        return voteHash;
    }

    /**
     * Returns the confirmation message hash.
     * 
     * @return confirmation message hash.
     */
    public String getConfirmationMessageHash() {
        return confirmationMessageHashService.hash(confirmationInformation);
    }

    private String sanitize(String value, Pattern pattern) {
        if (value == null) {
            return "";
        }
        if (!pattern.matcher(value).matches()) {
            return "Invalid";
        }
        return value;
    }
}
