// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using Microsoft.Teams.Api.Auth;

namespace Microsoft.Teams.Plugins.AspNetCore.Extensions;

public class TeamsValidationSettings
{
    public string OpenIdMetadataUrl;
    public List<string> Audiences = [];
    public List<string> Issuers;
    public string LoginEndpoint;

    public TeamsValidationSettings() : this(CloudEnvironment.Public)
    {
    }

    public TeamsValidationSettings(CloudEnvironment cloud)
    {
        LoginEndpoint = cloud.LoginEndpoint;
        OpenIdMetadataUrl = cloud.OpenIdMetadataUrl;
        Issuers = [
            cloud.TokenIssuer,
            "https://sts.windows.net/d6d49420-f39b-4df7-a1dc-d59a935871db/", // Emulator Auth v3.1, 1.0 token
            "https://login.microsoftonline.com/d6d49420-f39b-4df7-a1dc-d59a935871db/v2.0", // Emulator Auth v3.1, 2.0 token
            "https://sts.windows.net/f8cdef31-a31e-4b4a-93e4-5f571e91255a/", // Emulator Auth v3.2, 1.0 token
            "https://login.microsoftonline.com/f8cdef31-a31e-4b4a-93e4-5f571e91255a/v2.0", // Emulator Auth v3.2, 2.0 token
            "https://sts.windows.net/69e9b82d-4842-4902-8d1e-abc5b98a55e8/", // Copilot Auth v1.0 token
            "https://login.microsoftonline.com/69e9b82d-4842-4902-8d1e-abc5b98a55e8/v2.0", // Copilot Auth v2.0 token
        ];
    }

    public void AddDefaultAudiences(string ClientId)
    {
        if (ClientId is not null && !Audiences.Contains(ClientId))
            Audiences.Add(ClientId);

        var apiAudience = $"api://{ClientId}";
        if (ClientId is not null && !Audiences.Contains(apiAudience))
            Audiences.Add(apiAudience);
    }

    public IEnumerable<string> GetValidIssuersForTenant(string? tenantId)
    {
        var validIssuers = new List<string>();
        if (!string.IsNullOrEmpty(tenantId))
        {
            // Cloud-specific login endpoint issuer (e.g. https://login.microsoftonline.com/{tenantId}/).
            // Note: this is the tenant-prefixed login endpoint form, not the AAD v2.0
            // issuer (which ends in `/v2.0`).
            validIssuers.Add($"{LoginEndpoint}/{tenantId}/");
            // Azure AD v1 issuer (sts.windows.net) — some valid Microsoft Entra tokens
            // are still issued with the v1 issuer format.
            // See https://learn.microsoft.com/en-us/entra/identity-platform/access-tokens
            validIssuers.Add($"https://sts.windows.net/{tenantId}/");
        }
        else
        {
            // When no tenant ID is configured, issuer validation will be skipped.
            // This accepts tokens from any Azure AD tenant.
            System.Diagnostics.Trace.TraceWarning(
                "No tenant ID provided for Entra token validation. " +
                "Issuer validation will be skipped, accepting tokens from any tenant.");
        }
        return validIssuers;
    }

    public string GetTenantSpecificOpenIdMetadataUrl(string? tenantId)
    {
        return $"{LoginEndpoint}/{tenantId ?? "common"}/v2.0/.well-known/openid-configuration";
    }
}