{% set namespace_name = fmt_class(class_name(namespace.name)) %}
///
/// Copyright (c) 2022 Dropbox, Inc. All rights reserved.
///
/// Auto-generated by Stone, do not modify.
///

import Foundation
import SwiftyDropbox

/// Objective-C compatible routes for the {{ namespace.name }} namespace
/// For Swift routes see {{ namespace_name }}Routes
@objc
public class DBX{{ namespace_name }}Routes: NSObject {
    private let swift: {{ namespace_name }}Routes
    init(swift: {{ namespace_name }}Routes) {
        self.swift = swift
        self.client = swift.client.objc
    }

    public let client: DBX{{ transport_client_name }}

    {% for route in namespace.routes %}
    {% if valid_route_for_auth_type(route) is true and not route.deprecated %}
    {% for args_data in route_client_args(route) %}
    {{ route_doc(route) }}
    ///
    {% if route.attrs.get('scope') is not none %}
    /// - scope: {{ route.attrs.get('scope') }}
    ///
    {% endif %}
    {% for route_param_doc in route_param_docs(namespace, route, args_data) %}
    {{ route_param_doc }}
    {% endfor %}
    ///
    {{ route_returns_doc(route) }}
    {% set func_name = fmt_func(route.name, route.version) %}
    {% set objc_class = fmt_route_objc_class(namespace, route, args_data) %}
    {% set suffix = route_objc_func_suffix(args_data) %}
    {% set route_args_no_defaults = route_args(namespace, route, args_data, True, False) %}
    {% set route_args = route_args(namespace, route, args_data, True) %}
    @objc
    @discardableResult public func {{ func_name }}{{ suffix }}({{ route_args }}) -> {{ objc_class }} {
        {% if is_struct_type(route.arg_data_type) %}
        let swift = swift.{{ func_name }}({{ objc_init_args_to_swift(route.arg_data_type, args_data) }})
        {% elif is_union_type(route.arg_data_type) %}
        let swift = swift.{{ func_name }}({{ fmt_var(route.arg_data_type.name) }}: {{ fmt_var(route.arg_data_type.name) }}.swift)
        {% else %}
        let swift = swift.{{ func_name }}()
        {% endif %}
        return {{ objc_class }}(swift: swift)
    }

    {% if route_args != route_args_no_defaults %}
    {{ route_doc(route) }}
    ///
    {% if route.attrs.get('scope') is not none %}
    /// - scope: {{ route.attrs.get('scope') }}
    ///
    {% endif %}
    {{ route_returns_doc(route) }}
    @objc
    @discardableResult public func {{ func_name }}{{ suffix }}({{ route_args_no_defaults }}) -> {{ objc_class }} {
        {% if is_struct_type(route.arg_data_type) %}
        let swift = swift.{{ func_name }}({{ objc_init_args_to_swift(route.arg_data_type, args_data, False) }})
        {% elif is_union_type(route.arg_data_type) %}
        let swift = swift.{{ func_name }}({{ fmt_var(route.arg_data_type.name) }}: {{ fmt_var(route.arg_data_type.name) }}.swift)
        {% else %}
        let swift = swift.{{ func_name }}()
        {% endif %}
        return {{ objc_class }}(swift: swift)
    }

    {% endif %}
    {% endfor %}
    {% endif %}
    {% endfor %}
}

{% for route_args_data in routes_for_objc_requests(namespace) %}
{% set route = route_args_data[0] %}
{% if valid_route_for_auth_type(route) is true %}

{# do not redefine DBXRequests defined by the user auth client #}
{% if not objc_app_auth_route_wrapper_already_defined(route) %}
{% set args_data = route_args_data[1] %}
{% set request_object_name = request_object_name(route, args_data) %}
{% set result_serial_type = fmt_serial_type(route.result_data_type) %}
{% set error_serial_type = fmt_serial_type(route.error_data_type) %}
{% set result_type = route_objc_result_type(route, args_data) %}
{% set objc_data_type = fmt_objc_type(route.result_data_type) %}
@objc
public class {{ fmt_route_objc_class(namespace, route, args_data) }}: NSObject, DBXRequest {
    var swift: {{ request_object_name }}<{{ result_serial_type }}, {{ error_serial_type }}>

    init(swift: {{ request_object_name }}<{{ result_serial_type }}, {{ error_serial_type }}>) {
        self.swift = swift
    }

    @objc
    @discardableResult public func response(
        completionHandler: @escaping ({{ result_type }}) -> Void
    ) -> Self {
        self.response(queue: nil, completionHandler: completionHandler)
    }

    @objc
    @discardableResult public func response(
        queue: DispatchQueue?,
        completionHandler: @escaping ({{ result_type }}) -> Void
    ) -> Self {
        swift.response(queue: queue) { result, error in
            {% if route.error_data_type.name != 'Void' %}
            {% set error_type = 'DBX' + fmt_class(route.error_data_type.namespace.name) + fmt_class(route.error_data_type.name) %}
            {% set error_call = 'routeError, callError' %}
            var routeError: {{ error_type }}?
            var callError: DBXCallError?
            switch error {
            case .routeError(let box, _, _, _):
                routeError = {{ error_type }}(swift: box.unboxed)
                callError = nil
            default:
                routeError = nil
                callError = error?.objc
            }

            {% else %}
            {% set error_call = 'error?.objc' %}
            {% endif %}
            {% if route.result_data_type.name == 'Void' %}
            completionHandler({{ error_call }})
            {% elif request_object_name is in ['DownloadRequestFile', 'DownloadRequestMemory'] %}
            var objc: {{ objc_data_type }}? = nil
            var destination: {{ 'URL?' if request_object_name == 'DownloadRequestFile' else 'Data?' }} = nil
            if let swift = result {
                objc = {{ objc_result_from_swift(route.result_data_type, 'swift.0') }}
                destination = swift.1
            }
            completionHandler(objc, destination, {{ error_call }})
            {% else %}
            var objc: {{ objc_data_type }}? = nil
            if let swift = result {
                objc = {{ objc_result_from_swift(route.result_data_type) }}
            }
            completionHandler(objc, {{ error_call }})
            {% endif %}
        }
        return self
    }

    {% if request_object_name != 'RpcRequest' %}
    @objc
    public func progress(_ progressHandler: @escaping ((Progress) -> Void)) -> Self {
        swift.progress(progressHandler)
        return self
    }

    {% endif %}
    @objc
    public var clientPersistedString: String? { swift.clientPersistedString }

    @available(iOS 13.0, macOS 10.13, *)
    @objc
    public var earliestBeginDate: Date? { swift.earliestBeginDate }

    @objc
    public func persistingString(string: String?) -> Self {
        swift.persistingString(string: string)
        return self
    }

    @available(iOS 13.0, macOS 10.13, *)
    @objc
    public func settingEarliestBeginDate(date: Date?) -> Self {
        swift.settingEarliestBeginDate(date: date)
        return self
    }

    @objc
    public func cancel() {
        swift.cancel()
    }
}

{% endif %}
{% endif %}
{% endfor %}
