package dbaasui

import (
	"encoding/json"
	"fmt"
	"net/url"
	"strings"
)

// O11YRuntimeConfig is an optional, non-secret browser integration contract.
// Main API and login origins remain fixed even when this object is present.
type O11YRuntimeConfig struct {
	GSHost               string `json:"gsHost"`
	GSHostV2             string `json:"gsHostV2"`
	TestHostDomainSuffix string `json:"testHostDomainSuffix,omitempty"`
	NextGenBizType       string `json:"nextGenBizType,omitempty"`
	DedicatedBizType     string `json:"dedicatedBizType,omitempty"`
	DevTierBizType       string `json:"devTierBizType,omitempty"`
}

// RenderRuntimeConfig produces the public config.js mounted into one Remote
// session. It contains no credential and never accepts a configurable main API
// or Auth0 origin.
func RenderRuntimeConfig(o11y *O11YRuntimeConfig) ([]byte, error) {
	o11yJSON := []byte("null")
	if o11y != nil {
		if !validHTTPSOrigin(o11y.GSHost) || !validHTTPSOrigin(o11y.GSHostV2) {
			return nil, fmt.Errorf("o11y gsHost and gsHostV2 must be HTTPS origins")
		}
		var err error
		o11yJSON, err = json.MarshalIndent(o11y, "  ", "  ")
		if err != nil {
			return nil, fmt.Errorf("marshal o11y runtime config: %w", err)
		}
	}
	output := fmt.Sprintf(`;(() => {
  'use strict'
  const origin = window.location.origin
  const o11y = %s
  window.__CP9_CONFIG__ = Object.freeze({
    schemaVersion: 1,
    profile: 'cp9-dev',
    mainApiOrigin: origin,
    releaseEnv: 'dev',
    auth0Domain: 'tidb-dev.us.auth0.com',
    auth0ClientId: 'KiwWajLJ3pto8SsZ7F35NaqNhwnoRh1c',
    auth0CallbackPath: '/auth_redirect',
    auth0LogoutPath: '/',
    o11y: o11y === null ? null : Object.freeze(o11y),
    integrations: Object.freeze({
      analytics: false,
      sentry: false,
      recaptcha: false,
      stripe: false,
      reo: false
    })
  })
})()
`, o11yJSON)
	return []byte(output), nil
}

func validHTTPSOrigin(value string) bool {
	parsed, err := url.Parse(strings.TrimSpace(value))
	return err == nil && parsed.Scheme == "https" && parsed.Hostname() != "" && parsed.User == nil &&
		parsed.Path == "" && parsed.RawQuery == "" && parsed.Fragment == ""
}
