package urlrewrite

import "encoding/json"

func rewriteStringValue(input, oldPrefix, newPrefix string) (string, bool) {
	if oldPrefix == "" || newPrefix == "" {
		return input, false
	}
	if len(input) >= len(oldPrefix) && input[:len(oldPrefix)] == oldPrefix {
		return newPrefix + input[len(oldPrefix):], true
	}
	return input, false
}

func rewriteJSONContent(input, oldPrefix, newPrefix string) (string, bool, error) {
	var data any
	if err := json.Unmarshal([]byte(input), &data); err != nil {
		rewritten, changed := rewriteStringValue(input, oldPrefix, newPrefix)
		if changed {
			return rewritten, true, nil
		}
		return "", false, err
	}
	rewritten, changed := rewriteAny(data, oldPrefix, newPrefix)
	if !changed {
		return input, false, nil
	}
	out, err := json.Marshal(rewritten)
	if err != nil {
		return "", false, err
	}
	return string(out), true, nil
}

func rewriteAny(value any, oldPrefix, newPrefix string) (any, bool) {
	switch v := value.(type) {
	case map[string]any:
		changed := false
		for key, child := range v {
			newChild, childChanged := rewriteAny(child, oldPrefix, newPrefix)
			if childChanged {
				v[key] = newChild
				changed = true
			}
		}
		return v, changed
	case []any:
		changed := false
		for i, child := range v {
			newChild, childChanged := rewriteAny(child, oldPrefix, newPrefix)
			if childChanged {
				v[i] = newChild
				changed = true
			}
		}
		return v, changed
	case string:
		if rewritten, changed, err := rewriteJSONContent(v, oldPrefix, newPrefix); err == nil && changed {
			return rewritten, true
		}
		return rewriteStringValue(v, oldPrefix, newPrefix)
	default:
		return value, false
	}
}
