/*
 * Copyright (c) eHealth
 */
package be.ehealth.technicalconnector.beid;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Properties;

import javax.swing.JDialog;

import be.ehealth.technicalconnector.beid.domain.SpecialOrganisation;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.ClassRule;
import org.junit.Test;

import be.ehealth.technicalconnector.beid.domain.Address;
import be.ehealth.technicalconnector.beid.domain.Identity;
import be.ehealth.technicalconnector.config.ConfigFactory;
import be.ehealth.technicalconnector.config.ConfigValidator;
import be.ehealth.technicalconnector.service.sts.security.impl.beid.PinPadPanel;
import be.ehealth.technicalconnector.service.sts.security.impl.beid.impl.BeIDConnectorExternalGui;
import be.ehealth.technicalconnector.service.sts.security.impl.beid.impl.PinPadPanelImpl;
import be.ehealth.technicalconnector.session.Session;
import be.fedict.commons.eid.client.FileType;
import be.fedict.commons.eid.client.PINPurpose;
import be.fedict.commons.eid.consumer.tlv.TlvParser;
import be.fgov.ehealth.technicalconnector.tests.junit.rule.SessionRule;
import be.fgov.ehealth.technicalconnector.tests.utils.TestPropertiesLoader;


/**
 * IntegrationTest for BeIDInfo
 *
 * @author EHP
 */
public class BeIDInfoUserIntegrationTest {

    @ClassRule
    public static SessionRule rule = SessionRule.withInactiveSession().build();

    @Test
    public void validateIdentityMapping() throws Exception {

        final byte[] identityFile = BeIDCardFactory.getBeIDCard().readFile(FileType.Identity);
        final be.fedict.commons.eid.consumer.Identity expected = TlvParser.parse(identityFile, be.fedict.commons.eid.consumer.Identity.class);

        Identity actual = BeIDInfo.getInstance("validateMapping").getIdentity();


        Assert.assertEquals(expected.getCardDeliveryMunicipality(), actual.getCardDeliveryMunicipality());
        Assert.assertEquals(expected.getCardNumber(), actual.getCardNumber());
        Assert.assertEquals(expected.getCardValidityDateBegin().getTimeInMillis(), actual.getCardValidityDateBegin().getMillis());
        Assert.assertEquals(expected.getCardValidityDateEnd().getTimeInMillis(), actual.getCardValidityDateEnd().getMillis());
        Assert.assertEquals(expected.getChipNumber(), actual.getChipNumber());
        Assert.assertArrayEquals(expected.getData(), actual.getData());
        Assert.assertEquals(expected.getDateOfBirth().getTimeInMillis(), actual.getDateOfBirth().getMillis());
        Assert.assertEquals(expected.getDocumentType().name(), actual.getDocumentType().name());
        Assert.assertEquals(expected.getDuplicate(), actual.getDuplicate());
        Assert.assertEquals(expected.getFirstName(), actual.getFirstName());
        Assert.assertEquals(expected.getGender().name(), actual.getGender().name());
        Assert.assertEquals(expected.getMiddleName(), actual.getMiddleName());
        Assert.assertEquals(expected.getName(), actual.getName());
        Assert.assertEquals(expected.getNationality(), actual.getNationality());
        Assert.assertEquals(expected.getNationalNumber(), actual.getNationalNumber());
        Assert.assertEquals(expected.getNobleCondition(), actual.getNobleCondition());
        Assert.assertArrayEquals(expected.getPhotoDigest(), actual.getPhotoDigest());
        Assert.assertEquals(expected.getPlaceOfBirth(), actual.getPlaceOfBirth());
        SpecialOrganisation specialOrganisation = actual.getSpecialOrganisation();
        if (specialOrganisation != null) {
            Assert.assertEquals(expected.getSpecialOrganisation().name(), specialOrganisation.name());
        } else {
            Assert.assertEquals(expected.getSpecialOrganisation(), specialOrganisation);
        }
        Assert.assertEquals(expected.getSpecialStatus().name(), actual.getSpecialStatus().name());
        Assert.assertEquals(expected.isMemberOfFamily(), actual.isMemberOfFamily());

    }

    @Test
    public void validateAddressingMapping() throws Exception {

        final byte[] identityFile = BeIDCardFactory.getBeIDCard().readFile(FileType.Address);
        final be.fedict.commons.eid.consumer.Address expected = TlvParser.parse(identityFile, be.fedict.commons.eid.consumer.Address.class);

        Address actual = BeIDInfo.getInstance("validateMapping").getAddress();

        Assert.assertArrayEquals(expected.getData(), actual.getData());
        Assert.assertEquals(expected.getMunicipality(), actual.getMunicipality());
        Assert.assertEquals(expected.getStreetAndNumber(), actual.getStreetAndNumber());
        Assert.assertEquals(expected.getZip(), actual.getZip());


    }

    /**
     * Reads the identity card and checks the values received with the values in the properties file.
     */
    @Test
    public void readBeID() throws Exception {
        Properties props = TestPropertiesLoader.getProperties("/be.ehealth.technicalconnector.test.properties");

        BeIDInfo actual = BeIDInfo.getInstance("test");
        Assume.assumeTrue(props.getProperty("test.session.user").equals(actual.getIdentity().getNationalNumber()));
        Assert.assertEquals(props.getProperty("test.session.firstname"), actual.getIdentity().getFirstName());
        Assert.assertEquals(props.getProperty("test.session.lastname"), actual.getIdentity().getName());


    }


    @Test
    public void customDialog() throws Exception {
        PinPadPanel panel = new PinPadPanelImpl();

        final JDialog dialog = new JDialog((Frame) null, "Pincode", true);
        dialog.setSize(300, 420);
        dialog.getContentPane().add((Component) panel, BorderLayout.CENTER);
        panel.setActionListenerOnGoButton(new ActionListener() {

            @Override
            public void actionPerformed(final ActionEvent event) {
                dialog.dispose();
            }
        });

        dialog.setVisible(true);
        BeIDConnectorExternalGui.getInstance().setPIN(PINPurpose.AuthenticationSignature, panel.getPassWord());
        BeIDConnectorExternalGui.getInstance().setPIN(PINPurpose.NonRepudiationSignature, panel.getPassWord());


        ConfigValidator config = ConfigFactory.getConfigValidator();
        config.setProperty("beidcardgui.class", BeIDConnectorExternalGui.class.getName());
        config.setProperty("user.inss", BeIDInfo.getInstance("testCustomDialog").getIdentity().getNationalNumber());
        Session.getInstance().createSessionEidOnly();

    }


}
