// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements.  See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License.  You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"context"
	"os"
	"path/filepath"
	"testing"

	"github.com/apache/beam/sdks/v2/go/container/tools"
	"google.golang.org/protobuf/types/known/structpb"
)

func TestActivePidsRegistry(t *testing.T) {
	// Reset active PIDs
	activePids = nil

	activePids = append(activePids, 101)
	activePids = append(activePids, 102)

	pids := getActivePids()
	if len(pids) != 2 || pids[0] != 101 || pids[1] != 102 {
		t.Errorf("Expected active pids [101, 102], got %v", pids)
	}

	unregisterPid(101)
	pids = getActivePids()
	if len(pids) != 1 || pids[0] != 102 {
		t.Errorf("Expected active pids [102], got %v", pids)
	}

	unregisterPid(102)
	pids = getActivePids()
	if len(pids) != 0 {
		t.Errorf("Expected active pids empty, got %v", pids)
	}
}

func TestSetupProfilerConfig(t *testing.T) {
	st, err := structpb.NewStruct(map[string]interface{}{
		"options": map[string]interface{}{
			"profiler_agent": "coredump",
			"jobId":          "test-job",
		},
	})
	if err != nil {
		t.Fatalf("Failed to create structpb: %v", err)
	}

	po := tools.ParseOptionsFromProto(st, "")

	ctx := setupProfilerConfig(context.Background(), &tools.Logger{}, po)
	pcfg := getProfilerConfig(ctx)
	if pcfg == nil {
		t.Fatal("ProfilerConfig was nil")
	}

	if pcfg.Agent != "coredump" {
		t.Errorf("Expected agent coredump, got %s", pcfg.Agent)
	}
}

func TestIsProfilerDisengaged(t *testing.T) {
	tempDir, err := os.MkdirTemp("", "disengage_test")
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(tempDir)

	sentinelPath := filepath.Join(tempDir, "stop_sentinel")
	pcfg := &ProfilerConfig{
		StopSentinelPath: sentinelPath,
	}

	if isProfilerDisengaged(pcfg) {
		t.Error("Expected profiler NOT to be disengaged before sentinel creation")
	}

	// Create sentinel file
	if err := os.WriteFile(sentinelPath, []byte{}, 0644); err != nil {
		t.Fatal(err)
	}

	if !isProfilerDisengaged(pcfg) {
		t.Error("Expected profiler to be disengaged after sentinel creation")
	}
}

func TestCreatePystackSummary(t *testing.T) {
	t.Run("ExtractsGILThreadTrace", func(t *testing.T) {
		output := "Thread 1 (waiting):\n" +
			"  File \"worker.py\", line 10, in run\n" +
			"\n" +
			"Thread 2 (active, Has the GIL):\n" +
			"  File \"main.py\", line 42, in execute\n" +
			"  File \"db.py\", line 5, in query\n" +
			"\n" +
			"Thread 3 (idle):\n" +
			"  File \"server.py\", line 99, in listen\n"

		expected := "Thread 2 (active, Has the GIL):\n" +
			"  File \"main.py\", line 42, in execute\n" +
			"  File \"db.py\", line 5, in query\n"

		result := createPystackSummary(output)
		if result != expected {
			t.Errorf("Expected:\n%s\nGot:\n%s", expected, result)
		}
	})

	t.Run("FallbackSmallOutput", func(t *testing.T) {
		output := "Thread 1 (waiting):\n" +
			"  File \"worker.py\", line 10, in run"

		result := createPystackSummary(output)
		if result != output {
			t.Errorf("Expected identical output, got:\n%s", result)
		}
	})
}
