'''
This script demonstrates importing a repository from a `.zip` file into disy Cadenza using
the API key authentication of the Cadenza Management API.

This script imports the functions `build_mgmt_api_request_url` and
`sign_mgmt_api_request_url` from the file `cadenza_api_util.py` provided as part
of the developer documentation. Make sure to have both files in the same folder.
'''
import posixpath
import urllib.request
from urllib.parse import urljoin
from urllib.error import HTTPError, URLError
from datetime import datetime, timezone
from email.utils import format_datetime
from requests_toolbelt.multipart.encoder import MultipartEncoder
from cadenza_api_util import build_mgmt_api_request_url, sign_mgmt_api_request_url

if __name__ == '__main__':
    # see "accessmanagerapikey" config
    # **/client/apikey
    API_KEY = 'eV9rwLxYyuFs5cSPgueKYG6YLqoiP/yQgDXzehxal83FBXMZiTDCI4S1/MGcvjGv'
    # **/client/encodedSignatureKey
    SECRET = 'LApqIO0HfD7VhOCVLMuVo/JbmTiK8lUgGD+WQMw9kyM0'
    # **/client/clientId (is optional)
    CLIENT_ID = 'api-user'

    # only needed if more than one Repo-DB is defined in repositoryList.xml
    #REPOSITORY_SCHEMA_ID = 'REPO_DB'
    REPOSITORY_SCHEMA_ID = None

    CADENZA_BASE_URL = 'http://localhost:8080'
    BASE_PATH = '/cadenza'

    # Specify the repo-file and URL
    REPO_FILE_PATH = 'path/repository.zip'

    path = posixpath.join(BASE_PATH, 'public/adminapi/repositories/')

    # Specify the if-unmodified-since date to determine if an exisiting repo (in case
    # one exists) should be overwritten. This needs to be a RFC 1123 date representation.
    # To always overwrite, use a future date, to never overwrite, use a date way in the 
    # past, e.g. 'Thu, 01 Jan 1970 00:00:00 GMT'.
    if_unmodified_since_date = datetime(2025,9,15,8,15,12,0, timezone.utc)
    # 'Mon, 15 Sep 2025 08:15:12 GMT'
    if_unmodified_since_str = format_datetime(if_unmodified_since_date, usegmt=True)

    query = {}
    if REPOSITORY_SCHEMA_ID is not None:
        query = { 'repositorySchemaId': str(REPOSITORY_SCHEMA_ID) }

    # build and sign URL using imported functions from cadenza_api_util.py
    url = build_mgmt_api_request_url(urljoin(CADENZA_BASE_URL, path), query)
    signature = sign_mgmt_api_request_url(url, SECRET)

    # Prepare the multipart, the MultipartEncoder is used for the boundary handling
    with open(REPO_FILE_PATH, 'rb') as repo_file:
        multipart = MultipartEncoder(
          fields = { 'file': ('repository.zip', repo_file.read(), 'application/zip') }
        )

    # defining a params dict for the parameters to be sent to the API
    headers = {
        'X-Api-Key': API_KEY
      , 'X-Client-Id': CLIENT_ID
      , 'X-Request-Signature': signature
      , 'Content-Type': multipart.content_type
      , 'Content-Length': str(multipart.len)
      , 'Accept': 'application/json,application/problem+json;q=0.8'
      , 'If-Unmodified-Since': if_unmodified_since_str
    }

    # POST request is needed
    req = urllib.request.Request(url, data=multipart, headers=headers, method='POST')
    print(f'Request Method:      {req.method}')
    print(f'X-Request-Signature: {signature}')

    try:
        with urllib.request.urlopen(req) as response:
            response_body = response.read()
            print(f'Response Code:       {response.status}')
            print(f'Response:            {response_body.decode("utf-8")}')
    except HTTPError as e:
        print(f'Response Code:       {e.code}')
        print(f'Message:             {e.reason}')
    except URLError as e:
        print(f'Message:             {e.reason}')
