<commit_before>//
// Xcore
// Copyright © 2021 Xcore
// MIT license, see LICENSE file for details
//

import SwiftUI
@_implementationOnly import SafariServices

/// Provides functionality for opening a URL.
///
/// **Usage**
///
/// ```swift
/// struct ViewModel {
///     @Dependency(\.openUrl) var openUrl
///
///     func openMailApp() {
///         openUrl(.mailApp)
///     }
///
///     func openSettingsApp() {
///         openUrl(.settingsApp)
///     }
///
///     func openSomeUrl() {
///         openUrl(URL(string: "https://example.com"))
///     }
/// }
/// ```
public struct OpenURLClient: Hashable, Identifiable {
    public let id: String
    private let open: (AdaptiveURL) -> Void

    public init(id: String = #function, open: @escaping (AdaptiveURL) -> Void) {
        self.id = id
        self.open = open
    }

    /// Attempts to asynchronously open the resource at the specified URL.
    public func callAsFunction(_ url: AdaptiveURL) {
        open(url)
    }

    /// Attempts to asynchronously open the resource at the specified URL.
    public func callAsFunction(_ url: URL?) {
        guard let url = url else {
            return
        }

        open(.init(title: "", url: url))
    }

    public static func ==(lhs: Self, rhs: Self) -> Bool {
        lhs.id == rhs.id
    }

    public func hash(into hasher: inout Hasher) {
        hasher.combine(id)
    }
}

// MARK: - Variants

extension OpenURLClient {
    /// Returns system variant of `OpenURLClient`.
    public static var system: Self {
        .init { adaptiveUrl in
            guard let app = UIApplication.sharedOrNil else {
                return
            }

            let url = adaptiveUrl.url

            // Attempt to open standard urls using in-app Safari.
            if [.http, .https].contains(url.schemeType), let nvc = app.topNavigationController {
                let vc = SFSafariViewController(url: url)
                nvc.pushViewController(vc, animated: true)
            } else if app.canOpenURL(url) {
                app.appExtensionSafeOpen(url)
            }
        }
    }

    /// Returns noop variant of `OpenURLClient`.
    public static var noop: Self {
        .init { _ in }
    }

    #if DEBUG
    /// Returns failing variant of `OpenURLClient`.
    public static var failing: Self {
        .init { _ in
            internal_XCTFail("\(Self.self) is unimplemented")<commit_msg>Fixed the safari double nav<commit_after>//
// Xcore
// Copyright © 2021 Xcore
// MIT license, see LICENSE file for details
//

import SwiftUI
@_implementationOnly import SafariServices

/// Provides functionality for opening a URL.
///
/// **Usage**
///
/// ```swift
/// struct ViewModel {
///     @Dependency(\.openUrl) var openUrl
///
///     func openMailApp() {
///         openUrl(.mailApp)
///     }
///
///     func openSettingsApp() {
///         openUrl(.settingsApp)
///     }
///
///     func openSomeUrl() {
///         openUrl(URL(string: "https://example.com"))
///     }
/// }
/// ```
public struct OpenURLClient: Hashable, Identifiable {
    public let id: String
    private let open: (AdaptiveURL) -> Void

    public init(id: String = #function, open: @escaping (AdaptiveURL) -> Void) {
        self.id = id
        self.open = open
    }

    /// Attempts to asynchronously open the resource at the specified URL.
    public func callAsFunction(_ url: AdaptiveURL) {
        open(url)
    }

    /// Attempts to asynchronously open the resource at the specified URL.
    public func callAsFunction(_ url: URL?) {
        guard let url = url else {
            return
        }

        open(.init(title: "", url: url))
    }

    public static func ==(lhs: Self, rhs: Self) -> Bool {
        lhs.id == rhs.id
    }

    public func hash(into hasher: inout Hasher) {
        hasher.combine(id)
    }
}

// MARK: - Variants

extension OpenURLClient {
    /// Returns system variant of `OpenURLClient`.
    public static var system: Self {
        .init { adaptiveUrl in
            guard let app = UIApplication.sharedOrNil else {
                return
            }

            let url = adaptiveUrl.url

            // Attempt to open standard urls using in-app Safari.
            if [.http, .https].contains(url.schemeType), let nvc = app.topNavigationController {
                let vc = SFSafariViewController(url: url)
                // Present shows the Safari VC correctly in SwiftUI.
                nvc.present(vc, animated: true)
            } else if app.canOpenURL(url) {
                app.appExtensionSafeOpen(url)
            }
        }
    }

    /// Returns noop variant of `OpenURLClient`.
    public static var noop: Self {
        .init { _ in }
    }

    #if DEBUG
    /// Returns failing variant of `OpenURLClient`.
    public static var failing: Self {
        .init { _ in
            internal_XCTFail("\(Self.self) is unimplemented")
{'fraction_non_alphanumeric': 0.12306122448979592, 'fraction_numerical': 0.0016326530612244899, 'mean_word_length': 1.831311380704795, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1789996', 'n_tokens_mistral': 1461, 'n_tokens_neox': 1373, 'n_words': 419}