import { Injectable } from '@angular/core';
import { Guid } from '@common/types/guid';
import * as pk from 'pako';

@Injectable()
export class SamlLoginService {
    
    constructor() {}

    buildRelayState(spId: string, configurableLoginId: string): string {
        let uri = 'spId=' + spId;
        uri += '&configurableLoginId=' + configurableLoginId;
        return encodeURIComponent(uri);
    }
    
    resolveConfigurableLoginId(relayState: string): string {
        const decoded = decodeURIComponent(relayState);
        const routeParams = new URLSearchParams(decoded);
        return routeParams.has('configurableLoginId') ? routeParams.get('configurableLoginId') : undefined;
    }
    resolveSpId(relayState: string): string {
        const decoded = decodeURIComponent(relayState);
        const routeParams = new URLSearchParams(decoded);
        return routeParams.has('spId') ? routeParams.get('spId') : '';
    }
    
    getSamlLoginUrl(spEntityID: string, idpUrl: string, binding: string, assertionConsumerServiceUrl: string, configurableLoginId: string) {
        const now = new Date();
        let protocolBinding = '';
        switch (binding) {
            case "Redirect": protocolBinding = 'ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" '; break;
            case "Artifact": protocolBinding = 'ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" '; break;
            case "Post": protocolBinding = 'ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" '; break;
        }
        const authenticationRequest = '<saml2p:AuthnRequest xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" ID="_' + Guid.create() + '" Version="2.0" ' +
            'IssueInstant="' + now.toISOString() + '" ' +
            protocolBinding +
            'AssertionConsumerServiceUrl="' + assertionConsumerServiceUrl + '" ' +
            'Destination="' + idpUrl + '">' +
            '<saml2:Issuer>' + spEntityID + '</saml2:Issuer>' +
            '</saml2p:AuthnRequest>';
        const uint = new Uint8Array(authenticationRequest.length);
        for (let i = 0, j = authenticationRequest.length; i < j; ++i) {
            uint[i] = authenticationRequest.charCodeAt(i);
        }
        const base64String = btoa(pk.deflateRaw(uint, { to: 'string' }));
        const relayState = this.buildRelayState(spEntityID, configurableLoginId);
        const url = idpUrl + '?RelayState=' + relayState + '&SAMLRequest=' + encodeURIComponent(base64String);
        return url;
    }

}