# Copyright 2021-2025 Ping Identity Corporation. All Rights Reserved
#
# This code is to be used exclusively in connection with Ping Identity
# Corporation software or services. Ping Identity Corporation only offers
# such software or services to legal entities who have entered into a
# binding license agreement with Ping Identity Corporation.

# -*- coding: utf-8 -*-

import json
import time

# load tasks used by configuration file
from pyrock.lib.scheduler.tasks.StepTask import StepTask
from pyrock.tasks.scenario.gatling import GatlingTask
from shared.lib.utils.HttpCmd import HttpCmd
from pyrock.lib.PyRockRun import get_pyrock_run
from shared.lib.utils.constants import DEFAULT_DEPLOYMENT, IS_TENANT
from pyrock.tasks.deployment.configuration_idm import PrepareWorkloadTask
from pyrock.tasks.idm.general import DumpIDMIDWithAPITask

pyrock_run = get_pyrock_run()


class GatlingCustomPropsTask(GatlingTask):
    """Instead of hard coding value for '-Dsp_url' in conf.yaml, set it dynamically"""

    def _simulation_specific_java_sys_props(self):
        return f" -Dsp_url={pyrock_run.get_component('am', 'sp').url}"


class ConfigureSAML(StepTask):
    """Configure SAML on IDP and SP using Multinamespace Deployment"""

    def pre(self):
        """Pre method"""
        # Get deployment specific instances of the AM class for IDP and SP
        self.idp_am = pyrock_run.get_component("am", DEFAULT_DEPLOYMENT)
        self.sp_am = pyrock_run.get_component("am", "sp")

    def step1(self):
        """Configure hosted and remote IDP and SP and then add them to the COT"""

        # If this is IDC then cleanup federation first on IDP (tenant) as SP is deployed everytime
        if IS_TENANT:
            self.idp_am.cleanup_federation()

        idp_metadata = self.idp_am.create_hosted_idp(self.sp_am.url)
        sp_metadata = self.sp_am.create_hosted_sp()
        self.sp_am.import_saml_entity(idp_metadata)
        self.idp_am.import_saml_entity(sp_metadata)
        self.sp_am.create_cot()
        self.idp_am.create_cot()

    def step2(self):
        """Create user on SP for transient federation mapping"""
        token = self.sp_am.authenticate_user(self.sp_am.admin_username, self.sp_am.admin_password)
        headers = {
            "iPlanetDirectoryPro": token.json()["tokenId"],
            "Content-Type": "application/json",
            "Accept-API-Version": "resource=3.0, protocol=2.1",
        }
        data = {
            "username": "transient",
            "userpassword": self.sp_am.admin_password,
            "employeenumber": 0,
            "mail": "transient@forgerock.com",
            "telephoneNumber": "6669876987",
        }
        create_url = f"{self.sp_am.url}/json/realms/root/users/?_action=create"

        http_cmd = HttpCmd()
        http_cmd.post(url=create_url, headers=headers, json_data=data, expected_status=201)
        http_cmd.close()

        # TODO: Configure SP to ignore profile hence making the authentication faster on SP side

    def step3(self):
        """Patch the tree to be used for SP"""
        token = self.idp_am.authenticate_user(self.idp_am.admin_username, self.idp_am.admin_password)
        headers = {
            "iPlanetDirectoryPro": token.json()["tokenId"],
            "Content-Type": "application/json",
            "Accept-API-Version": "protocol=2.1,resource=1.0",
        }
        #
        """'Fetch the payload for sp entity"""
        response = HttpCmd().get(
            url=f"{self.idp_am.url}/json/realms/root/realm-config/saml2/remote/c3A", headers=headers
        )
        response_dict = response.json()
        """Update the tree Configuration for sp"""

        response_dict["serviceProvider"]["advanced"]["treeConfiguration"]["treeName"] = "Login"
        HttpCmd().put(
            url=f"{self.idp_am.url}/json/realms/root/realm-config/saml2/remote/c3A",
            headers=headers,
            json_data=response_dict,
        )

    def step4(self):
        """Reduce the replication purge delay"""

        ds_cts_idp = pyrock_run.get_component("ds-cts", DEFAULT_DEPLOYMENT)
        ds_cts_sp = pyrock_run.get_component("ds-cts", "sp")

        ds_cts_idp.set_replication_purge_delay(1800)
        ds_cts_sp.set_replication_purge_delay(1800)
