/*
    _trop_load_plugin -- Resolve the platform-specific compiled plugin binary.

    Detects the host operating system and CPU architecture, then searches
    for the corresponding plugin file in the following order:

      0. Same directory as this ado-file (net install layout).
      1. Relative to this ado-file (../plugin/).
      2. c(pwd)/trop_stata/plugin/
      3. c(pwd)/../plugin/
      4. c(pwd)/plugin/
      5. Along the adopath (PERSONAL, PLUS, SITE).

    Supported platforms:
      macOS ARM64, macOS x64, Linux x64, Windows x64.

    Returns via c_local:
      _plugin_name      Plugin filename.
      _plugin_path      Resolved absolute path to the binary.
      _platform_desc    Human-readable platform label.

    Exit codes:
      198   Unsupported OS or architecture.
      601   Plugin binary not found in any search path.
*/

program define _trop_load_plugin
    version 17.0

    local os = c(os)
    local machine = c(machine_type)

    // Detect macOS: c(os) returns "Unix" on some macOS configurations
    local is_mac_machine = strpos("`machine'", "Mac")
    local is_apple_silicon = strpos("`machine'", "Apple Silicon")
    local is_arm = strpos("`machine'", "ARM")
    local is_arm64 = strpos("`machine'", "arm64")

    local is_macos = 0
    if "`os'" == "MacOSX" {
        local is_macos = 1
    }
    else if "`os'" == "Unix" & `is_mac_machine' > 0 {
        local is_macos = 1
    }

    // Map platform to plugin filename
    if `is_macos' {
        if `is_apple_silicon' > 0 | `is_arm' > 0 | `is_arm64' > 0 {
            local plugin_name "trop_macos_arm64.plugin"
            local platform_desc "macOS ARM64 (Apple Silicon)"
        }
        else {
            local plugin_name "trop_macos_x64.plugin"
            local platform_desc "macOS x64 (Intel)"
        }
    }
    else if "`os'" == "Unix" {
        local plugin_name "trop_linux_x64.plugin"
        local platform_desc "Linux x64"
    }
    else if "`os'" == "Windows" {
        local plugin_name "trop_windows_x64.plugin"
        local platform_desc "Windows x64"
    }
    else {
        di as error "Unsupported platform: `os' (`machine')"
        di as error "This package supports: macOS (ARM64/x64), Linux x64, Windows x64."
        exit 198
    }

    // Search for the plugin binary across candidate locations
    local plugin_path ""

    // (0) Same directory as this ado file (net install places plugin alongside ado)
    capture findfile _trop_load_plugin.ado
    if !_rc {
        local ado_fullpath "`r(fn)'"
        // Normalize path separators (Windows uses backslash)
        local ado_fullpath : subinstr local ado_fullpath "\" "/", all
        // Extract directory containing this ado file
        local _spos0 = strrpos("`ado_fullpath'", "/")
        if `_spos0' > 0 {
            local _ado_dir0 = substr("`ado_fullpath'", 1, `_spos0')
            capture confirm file "`_ado_dir0'`plugin_name'"
            if !_rc {
                local plugin_path "`_ado_dir0'`plugin_name'"
            }
        }
    }

    // (1) Relative to this ado-file (../plugin/ for development layout)
    if "`plugin_path'" == "" {
    capture findfile _trop_load_plugin.ado
    if !_rc {
        local ado_fullpath "`r(fn)'"
        // Normalize path separators (Windows uses backslash)
        local ado_fullpath : subinstr local ado_fullpath "\" "/", all
        // (1a) Replace /ado/ segment with /plugin/ in the resolved path
        local _plugin_candidate : subinstr local ado_fullpath ///
            "/ado/_trop_load_plugin.ado" "/plugin/`plugin_name'"
        if "`_plugin_candidate'" != "`ado_fullpath'" {
            capture confirm file "`_plugin_candidate'"
            if !_rc {
                local plugin_path "`_plugin_candidate'"
            }
        }
        // (1b) Traverse to parent directory of ado/ and check plugin/
        if "`plugin_path'" == "" {
            local _spos = strrpos("`ado_fullpath'", "/")
            if `_spos' > 0 {
                local _ado_dir = substr("`ado_fullpath'", 1, `_spos' - 1)
                local _spos2 = strrpos("`_ado_dir'", "/")
                if `_spos2' > 0 {
                    local _pkg_root = substr("`_ado_dir'", 1, `_spos2' - 1)
                    capture confirm file "`_pkg_root'/plugin/`plugin_name'"
                    if !_rc {
                        local plugin_path "`_pkg_root'/plugin/`plugin_name'"
                    }
                }
            }
        }
    }
    }

    // (2)--(4) Paths relative to the current working directory
    local pwd = c(pwd)

    if "`plugin_path'" == "" {
        capture confirm file "`pwd'/trop_stata/plugin/`plugin_name'"
        if !_rc {
            local plugin_path "`pwd'/trop_stata/plugin/`plugin_name'"
        }
    }

    if "`plugin_path'" == "" {
        capture confirm file "`pwd'/../plugin/`plugin_name'"
        if !_rc {
            local plugin_path "`pwd'/../plugin/`plugin_name'"
        }
    }

    if "`plugin_path'" == "" {
        capture confirm file "`pwd'/plugin/`plugin_name'"
        if !_rc {
            local plugin_path "`pwd'/plugin/`plugin_name'"
        }
    }

    // (5) Search along adopath
    if "`plugin_path'" == "" {
        capture findfile `plugin_name'
        if !_rc {
            local plugin_path = r(fn)
        }
    }

    // Report failure with diagnostic information
    if "`plugin_path'" == "" {
        di as error "Plugin binary not found: `plugin_name'"
        di as error ""
        di as error "Platform: `platform_desc'"
        di as error "Current directory: `pwd'"
        di as error ""
        di as error "Locations searched:"
        if "`ado_fullpath'" != "" {
            di as error "  0. Same dir as ado: `ado_fullpath' -> ./"
            di as error "  1. Relative to ado file: `ado_fullpath' -> ../plugin/"
        }
        else {
            di as error "  0-1. (ado file not found in adopath)"
        }
        di as error "  2. `pwd'/trop_stata/plugin/"
        di as error "  3. `pwd'/../plugin/"
        di as error "  4. `pwd'/plugin/"
        di as error "  5. adopath (PERSONAL, PLUS, SITE)"
        di as error ""
        di as error "Ensure the package directory structure is intact,"
        di as error "or add the ado directory to adopath:"
        di as error `"  . adopath + "/path/to/trop_stata/ado""'
        exit 601
    }

    // Return resolved plugin details to the caller
    c_local _plugin_name `plugin_name'
    c_local _plugin_path `plugin_path'
    c_local _platform_desc `platform_desc'
end