# --------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# Code generated by Microsoft (R) Python Code Generator.
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
# --------------------------------------------------------------------------

import json
from typing import Any, IO, Mapping, Optional, Union

from .._utils.model_base import Model, SdkJSONEncoder


# file-like tuple could be `(filename, IO (or bytes))` or `(filename, IO (or bytes), content_type)`
FileContent = Union[str, bytes, IO[str], IO[bytes]]

FileType = Union[
    # file (or bytes)
    FileContent,
    # (filename, file (or bytes))
    tuple[Optional[str], FileContent],
    # (filename, file (or bytes), content_type)
    tuple[Optional[str], FileContent, Optional[str]],
]


def serialize_multipart_data_entry(data_entry: Any) -> Any:
    if isinstance(data_entry, (list, tuple, dict, Model)):
        return json.dumps(data_entry, cls=SdkJSONEncoder, exclude_readonly=True)
    return data_entry


def prepare_multipart_form_data(
    body: Mapping[str, Any], multipart_fields: list[str], data_fields: list[str]
) -> list[FileType]:
    files: list[FileType] = []
    for multipart_field in multipart_fields:
        multipart_entry = body.get(multipart_field)
        if isinstance(multipart_entry, list):
            files.extend([(multipart_field, e) for e in multipart_entry])
        elif multipart_entry:
            files.append((multipart_field, multipart_entry))

    # if files is empty, sdk core library can't handle multipart/form-data correctly, so
    # we put data fields into files with filename as None to avoid that scenario.
    for data_field in data_fields:
        data_entry = body.get(data_field)
        if data_entry:
            files.append((data_field, str(serialize_multipart_data_entry(data_entry))))

    return files
