# validation_rest.py
# version 1.0.0 (2026-06-17T01:31Z)
# author: David Ireland <https://di-mgt.com.au/contact>
# copyright (c) 2026 DI Management Services Pty Ltd
# SPDX-License-Identifier: Apache-2.0
# Description: REST validation client for the FirmaSAT validation service.

import requests
import json
import os
import base64


def validate(xmlfile, certfile_or_string=""):
    """Validate XML data with the FirmaSAT validation REST API.

    Args:
        xmlfile (str): Path to the XML input file.
        certfile_or_string (str, optional): PAC certificate file path, PEM/Base64
            certificate text file, or base64 string. Defaults to "".

    Returns:
        int: Result code returned by the validation service, or -1 on error.

    Raises:
        FileNotFoundError: If certfile_or_string is treated as a file path that
            does not exist.
        ValueError: If certfile_or_string cannot be interpreted as a valid certificate.
    """
    url = "https://di-mgt.com.au/cryptosys/api/fsa_validation"
    api_token = "YOUR_API_TOKEN_HERE"  # Replace with your own api-token
    print(f"FILE: {xmlfile}")
 
    def encode_file_to_base64(file_path):
        with open(file_path, 'rb') as f:
            binary_data = f.read()
        return base64.b64encode(binary_data).decode('utf-8')

    def read_text_file(file_path):
        with open(file_path, 'r', encoding='utf-8') as f:
            content = f.read()
        return content

    # Read in XML input data from file...
    xml_content = read_text_file(xmlfile)
    # Deal with optional PAC certificate...
    cert_content = ""
    if certfile_or_string:
        # Could be a filename or a base64 string
        if (len(certfile_or_string) > 250 and not os.path.exists(certfile_or_string)):
            cert_content = certfile_or_string
        else: # Short string, so must be a filename
            if not os.path.exists(certfile_or_string):
                raise FileNotFoundError(f"File '{certfile_or_string}' not found")
            # Certificate file could be binary .cer or textual PEM .crt or plain base64
            # Examine first byte to guess at form
            with open(certfile_or_string, 'rb') as f:
                firstbyte = f.read(1)
            if firstbyte == b'0':   # Binary
                cert_content = encode_file_to_base64(certfile_or_string)
            elif firstbyte == b'M' or firstbyte == b'-':  # Base64 or PEM
                cert_content = read_text_file(certfile_or_string)
            else:
                raise ValueError(f"{certfile_or_string} is not a valid certificate")
    # print(cert_content)

    # Setup payload
    payload = {"api-token": api_token,"xmldata": xml_content, "pac-cert": cert_content}
    # print(payload)

    # Do the business with the REST API...
    response = requests.post(url, json=payload)

    # Show the response...
    # print("RESPONSE:")
    # print(response.text)
    data = json.loads(response.text)
    result_code = -1  # default -1 => error
    # Fix the inner object by loading the string
    try:
        data['validation-result'] = json.loads(data['validation-result'])
        result_code = int(data['validation-result']['result-code'], base=16)
    except:
        pass
    print(json.dumps(data, indent=2))
    print(f"RESULT-CODE={result_code}")
    return result_code


def main():
    # Requires these two files in the CWD
    validate("cfdv40-ejemplo-signed-tfd.xml", "pac.cer")  # binary cert
 

if __name__ == "__main__":
    main()