// 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"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"sync"
	"time"

	"github.com/apache/beam/sdks/v2/go/container/tools"
)

type profilerConfigKeyType struct{}

var (
	profilerConfigKey profilerConfigKeyType
	profilerMu        sync.Mutex
	cleanupCallbacks  []func(ctx context.Context, logger *tools.Logger)
)

// registerCleanupCallback registers a function to be executed synchronously during container shutdown.
// This allows individual profiling agents to perform the final iteration of profile post processing.
func registerCleanupCallback(cb func(ctx context.Context, logger *tools.Logger)) {
	cleanupCallbacks = append(cleanupCallbacks, cb)
}

// ProfilerConfig holds all pre-computed profiling parameters.
type ProfilerConfig struct {
	Enabled                bool
	Agent                  string
	ExtraArgs              []string
	ExtraEnvVars           []string
	Location               string
	TempLocation           string
	BaseTempDir            string
	StopSentinelPath       string
	GcsDestPath            string
	UploadIntervalSec      int
	StopAfterSec           int
	StopAfterCrash         bool
	PostprocessIntervalSec int
	GcloudAvailable        bool
}

// setupProfilerConfig parses PipelineOptions and stores a resolved ProfilerConfig in the context.
func setupProfilerConfig(ctx context.Context, logger *tools.Logger, po *tools.PipelineOptions) context.Context {
	agent, err := po.GetString("profiler_agent")
	if err != nil || agent == "" {
		return ctx
	}

	baseTempDir, err := po.GetString("profile_temp_location")
	if err != nil || baseTempDir == "" {
		baseTempDir = filepath.Join(*semiPersistDir, "profiles")
	}

	jobId, err := po.GetString("jobId")
	if err != nil || jobId == "" {
		jobId = os.Getenv("JOB_ID")
	}
	if jobId == "" {
		jobId = os.Getenv("JOB_NAME")
	}
	if jobId == "" {
		jobId = "BEAM_JOB"
	}
	hostname, _ := os.Hostname()
	if hostname == "" {
		hostname = "default-worker"
	}

	tempLocation := filepath.Join(baseTempDir, jobId, hostname)
	sentinelPath := filepath.Join(tempLocation, fmt.Sprintf(".profiler_disengaged_%s_%s", jobId, hostname))

	var gcsDestPath string
	gcloudAvailable := false
	profileLocation, err := po.GetString("profile_location")
	if err != nil || profileLocation == "" {
		logger.Printf(ctx, "profile_location not specified, profiles will only be stored locally.")
	} else if strings.HasPrefix(profileLocation, "gs://") {
		gcsDestPath = strings.TrimSuffix(profileLocation, "/")
		if _, err := exec.LookPath("gcloud"); err == nil {
			gcloudAvailable = true
		} else {
			logger.Errorf(ctx, "gcloud is not available, profiles will not be uploaded.")
		}
	}

	profilerExtraArgs, err := po.GetStringSlice("profiler_extra_args")
	if err != nil {
		profilerExtraArgs = []string{}
	}
	profilerExtraEnvVars, err := po.GetStringSlice("profiler_extra_env_vars")
	if err != nil {
		profilerExtraEnvVars = []string{}
	}

	profileUploadIntervalSec, err := po.GetInt("profile_upload_interval_sec")
	if err != nil {
		profileUploadIntervalSec = 300
		logger.Printf(ctx, "Using default profile_upload_interval_sec: %v", profileUploadIntervalSec)
	}
	profilerStopAfterSec, err := po.GetInt("profiler_stop_after_sec")
	if err != nil {
		profilerStopAfterSec = 0
	}
	profilerStopAfterCrash, err := po.GetBool("profiler_stop_after_crash")
	if err != nil {
		profilerStopAfterCrash = false
	}
	profilePostprocessIntervalSec, err := po.GetInt("profile_postprocess_interval_sec")
	if err != nil {
		profilePostprocessIntervalSec = 600
		logger.Printf(ctx, "Using default profile_postprocess_interval_sec: %v", profilePostprocessIntervalSec)
	}

	config := &ProfilerConfig{
		Enabled:                true,
		Agent:                  agent,
		ExtraArgs:              profilerExtraArgs,
		ExtraEnvVars:           profilerExtraEnvVars,
		Location:               profileLocation,
		BaseTempDir:            baseTempDir,
		TempLocation:           tempLocation,
		StopSentinelPath:       sentinelPath,
		GcsDestPath:            gcsDestPath,
		UploadIntervalSec:      profileUploadIntervalSec,
		StopAfterSec:           profilerStopAfterSec,
		StopAfterCrash:         profilerStopAfterCrash,
		PostprocessIntervalSec: profilePostprocessIntervalSec,
		GcloudAvailable:        gcloudAvailable,
	}

	return context.WithValue(ctx, profilerConfigKey, config)
}

// getProfilerConfig extracts the ProfilerConfig from the context.
func getProfilerConfig(ctx context.Context) *ProfilerConfig {
	if cfg, ok := ctx.Value(profilerConfigKey).(*ProfilerConfig); ok {
		return cfg
	}
	return nil
}

// startProfilerBackgroundTasks initializes profiling locations and runs background tasks (GCS sync, post-processing loops) if profiling is enabled.
func startProfilerBackgroundTasks(ctx context.Context, logger *tools.Logger) {
	pcfg := getProfilerConfig(ctx)
	if pcfg == nil {
		return
	}

	logger.Printf(ctx, "Worker will be configured with profiler agent enabled.")
	logger.Printf(ctx, "ProfilerAgent: %v", pcfg.Agent)
	logger.Printf(ctx, "ProfilerExtraArgs: %v", pcfg.ExtraArgs)
	logger.Printf(ctx, "ProfilerExtraEnvVars: %v", pcfg.ExtraEnvVars)
	logger.Printf(ctx, "ProfileLocation: %v", pcfg.Location)
	logger.Printf(ctx, "ProfileTempLocation: %v", pcfg.BaseTempDir)
	logger.Printf(ctx, "ProfileUploadIntervalSec: %v", pcfg.UploadIntervalSec)
	logger.Printf(ctx, "ProfilerStopAfterSec: %v", pcfg.StopAfterSec)
	logger.Printf(ctx, "ProfilerStopAfterCrash: %v", pcfg.StopAfterCrash)
	logger.Printf(ctx, "ProfilePostprocessIntervalSec: %v", pcfg.PostprocessIntervalSec)
	if err := os.MkdirAll(pcfg.TempLocation, 0755); err != nil {
		logger.Warnf(ctx, "Failed to create ProfileTempLocation: %v", err)
	}

	if pcfg.GcsDestPath != "" && pcfg.GcloudAvailable {
		if pcfg.UploadIntervalSec > 0 {
			go func() {
				for {
					select {
					case <-ctx.Done():
						return
					case <-time.After(time.Duration(pcfg.UploadIntervalSec) * time.Second):
						// TODO(tvalentyn): Consider a periodic cleanup as well to save local disk space.
						syncProfilesToGCS(ctx, logger, pcfg.BaseTempDir, pcfg.GcsDestPath)
					}
				}
			}()
		}
	}

	if pcfg.PostprocessIntervalSec > 0 {
		if pcfg.Agent == "memray" {
			go postProcessProfilesLoop(ctx, logger, pcfg)
			registerCleanupCallback(func(ctx context.Context, logger *tools.Logger) {
				runPostProcessingSweep(ctx, logger, pcfg.TempLocation, pcfg.PostprocessIntervalSec)
			})
		}

		if pcfg.Agent == "coredump" {
			go monitorCoredumpsLoop(ctx, logger, pcfg)
			registerCleanupCallback(func(ctx context.Context, logger *tools.Logger) {
				processNewCoredumps(ctx, logger, pcfg)
			})
		}
	}

}

// maybeWithProfiler builds the execution arguments and environment variables if profiling is enabled and active.
func maybeWithProfiler(
	ctx context.Context,
	logger *tools.Logger,
	workerId string,
	currentProg string,
	currentArgs []string,
	currentEnv map[string]string,
) (string, []string, map[string]string, bool) {
	pcfg := getProfilerConfig(ctx)
	if pcfg == nil {
		return currentProg, currentArgs, currentEnv, false
	}

	if _, err := os.Stat(pcfg.StopSentinelPath); err == nil {
		return currentProg, currentArgs, currentEnv, false
	}

	prog := currentProg
	var args []string
	// Copy env
	env := make(map[string]string)
	for k, v := range currentEnv {
		env[k] = v
	}

	if pcfg.Agent == "memray" {
		timeSuffix := time.Now().Format("20060102150405")
		memrayFile := filepath.Join(pcfg.TempLocation, fmt.Sprintf("memray-%s-%s.bin", workerId, timeSuffix))
		args = []string{"-m", "memray", "run"}
		args = append(args, pcfg.ExtraArgs...)
		args = append(args, "-o", memrayFile, "-m", sdkHarnessEntrypoint)
	} else if pcfg.Agent == "tcmalloc" {
		tcmallocHeapPath := filepath.Join(pcfg.TempLocation, fmt.Sprintf("tcmalloc-%s", workerId))
		existingPreload := os.Getenv("LD_PRELOAD")
		if existingPreload != "" {
			env["LD_PRELOAD"] = existingPreload + ":libtcmalloc.so.4"
		} else {
			env["LD_PRELOAD"] = "libtcmalloc.so.4"
		}
		env["HEAPPROFILE"] = tcmallocHeapPath
		args = currentArgs
	} else if pcfg.Agent == "coredump" {
		// No wrapping of the executable is needed for coredump analysis.
		args = currentArgs
	} else {
		prog = pcfg.Agent
		args = append(append([]string{}, pcfg.ExtraArgs...), currentProg)
		args = append(args, currentArgs...)
	}

	for _, envVar := range pcfg.ExtraEnvVars {
		parts := strings.SplitN(envVar, "=", 2)
		if len(parts) == 2 {
			env[parts[0]] = parts[1]
		} else {
			logger.Errorf(ctx, "Failed to parse profiler extra environment variable: %v. Expected format KEY=VALUE", envVar)
		}
	}

	return prog, args, env, true
}

// stopProfiling creates a dummy file at StopSentinelPath to signal that profiling should stop.
func stopProfiling(ctx context.Context) error {
	pcfg := getProfilerConfig(ctx)
	if pcfg == nil {
		return nil
	}
	f, err := os.Create(pcfg.StopSentinelPath)
	if err == nil {
		f.Close()
	}
	return err
}

// isProfilerDisengaged checks if the stop sentinel file exists.
func isProfilerDisengaged(pcfg *ProfilerConfig) bool {
	if _, err := os.Stat(pcfg.StopSentinelPath); err == nil {
		return true
	}
	return false
}

// syncProfilesToGCS uploads newly created local memory profiles to the designated GCS target path using gcloud storage.
func syncProfilesToGCS(ctx context.Context, logger *tools.Logger, localDir, gcsDest string) {
	entries, err := os.ReadDir(localDir)
	if err != nil || len(entries) == 0 {
		return
	}

	logger.Printf(ctx, "Syncing profiles from %s to %s", localDir, gcsDest)

	cmd := exec.CommandContext(ctx, "gcloud", "storage", "rsync", "-r", localDir, gcsDest)
	if err := cmd.Run(); err != nil {
		logger.Warnf(ctx, "Failed to sync profiles to GCS: %v", err)
	} else {
		logger.Printf(ctx, "Successfully synced profiles to GCS.")
	}
}

// postProcessProfilesLoop runs a background loop that periodically triggers profile post-processing if enabled.
func postProcessProfilesLoop(ctx context.Context, logger *tools.Logger, pcfg *ProfilerConfig) {
	for {
		runPostProcessingSweep(ctx, logger, pcfg.TempLocation, pcfg.PostprocessIntervalSec)

		if isProfilerDisengaged(pcfg) {
			return
		}

		select {
		case <-ctx.Done():
			return
		case <-time.After(time.Duration(pcfg.PostprocessIntervalSec) * time.Second):
			// Block until the sleep completes before starting the next sweep
		}
	}
}

// runPostProcessingSweep scans the profiles directory and launches sequential postprocessing for newly updated profiles.
func runPostProcessingSweep(ctx context.Context, logger *tools.Logger, profilesDir string, intervalSec int) {
	profilerMu.Lock()
	defer profilerMu.Unlock()

	files, err := os.ReadDir(profilesDir)
	if err != nil {
		return
	}

	for _, file := range files {
		name := file.Name()
		if !strings.HasSuffix(name, ".bin") || strings.HasPrefix(name, ".") {
			continue
		}

		binPath := filepath.Join(profilesDir, name)
		binInfo, err := os.Stat(binPath)
		if err != nil || binInfo.Size() == 0 {
			continue
		}

		peakHtml := strings.TrimSuffix(binPath, ".bin") + ".html"
		leaksHtml := strings.TrimSuffix(binPath, ".bin") + "_leaks.html"

		filename := filepath.Base(binPath)
		peakReportStale := needsProcessing(binInfo, peakHtml)
		leakReportStale := needsProcessing(binInfo, leaksHtml)

		if peakReportStale || leakReportStale {
			binSizeMb := float64(binInfo.Size()) / (1024 * 1024)
			logger.Printf(ctx, "Post-processing profile %s of size %.2f MB", filename, binSizeMb)
		}

		// 1. Peak Flamegraph
		if peakReportStale {
			tmpPath := peakHtml + ".tmp"
			cmd1 := exec.CommandContext(ctx, "python", "-m", "memray", "flamegraph", "-f", "-o", tmpPath, binPath)
			if err := cmd1.Run(); err != nil {
				logger.Warnf(ctx, "Failed to generate peak flamegraph for %s: %v", filename, err)
			} else {
				if err := os.Rename(tmpPath, peakHtml); err != nil {
					logger.Warnf(ctx, "Failed to rename peak flamegraph for %s: %v", filename, err)
				} else {
					logger.Printf(ctx, "Successfully updated peak flamegraph for %s", filename)
					_ = os.Chtimes(peakHtml, binInfo.ModTime(), binInfo.ModTime())
				}
			}
		}

		// 2. Leaks Flamegraph
		if leakReportStale {
			tmpPath := leaksHtml + ".tmp"
			cmd2 := exec.CommandContext(ctx, "python", "-m", "memray", "flamegraph", "-f", "--leaks", "-o", tmpPath, binPath)
			if err := cmd2.Run(); err != nil {
				logger.Warnf(ctx, "Failed to generate leaks flamegraph for %s: %v", filename, err)
			} else {
				if err := os.Rename(tmpPath, leaksHtml); err != nil {
					logger.Warnf(ctx, "Failed to rename leaks flamegraph for %s: %v", filename, err)
				} else {
					logger.Printf(ctx, "Successfully updated leaks flamegraph for %s", filename)
					_ = os.Chtimes(leaksHtml, binInfo.ModTime(), binInfo.ModTime())
				}
			}
		}
	}
}

func needsProcessing(binInfo os.FileInfo, path string) bool {
	info, err := os.Stat(path)
	if os.IsNotExist(err) {
		return true
	}
	if err != nil {
		return true
	}
	// Don't regenerate when there were no updates to the profile.
	return binInfo.ModTime().After(info.ModTime())
}

func monitorCoredumpsLoop(ctx context.Context, logger *tools.Logger, pcfg *ProfilerConfig) {
	if pcfg.PostprocessIntervalSec <= 0 {
		return
	}

	interval := time.Duration(pcfg.PostprocessIntervalSec) * time.Second
	logger.Printf(ctx, "Monitoring core dumps every %v", interval)

	ticker := time.NewTicker(interval)
	defer ticker.Stop()

	for {
		select {
		case <-ctx.Done():
			return
		case <-ticker.C:
			processNewCoredumps(ctx, logger, pcfg)
			if isProfilerDisengaged(pcfg) {
				return
			}
		}
	}
}

func processNewCoredumps(ctx context.Context, logger *tools.Logger, pcfg *ProfilerConfig) {
	profilerMu.Lock()
	defer profilerMu.Unlock()

	// We expect the runner runtime environment to set the core pattern
	// to /tmp/beam_coredump.%e.%p or similar. To do that, we pass
	// the --experiment=core_pattern pipeline option, which can be interpreted by a runner.
	coreDir := "/tmp"
	files, err := os.ReadDir(coreDir)
	if err != nil {
		return
	}

	prefix := "beam_coredump."

	for _, file := range files {
		if file.IsDir() {
			continue
		}
		name := file.Name()
		if !strings.HasPrefix(name, prefix) {
			continue
		}

		corePath := filepath.Join(coreDir, name)
		var info os.FileInfo
		var err error

		for {
			info, err = os.Stat(corePath)
			if err != nil || time.Since(info.ModTime()) >= 2*time.Second {
				break
			}
			// Wait for the core file to finish being written.
			time.Sleep(500 * time.Millisecond)
		}
		if err != nil {
			continue
		}

		logger.Printf(ctx, "Found core dump file: %s (%d bytes)", name, info.Size())

		// Find python executable. Since the worker might be running in a venv,
		// we look for "python" in the PATH.
		pythonProg := "python"
		if path, err := exec.LookPath("python"); err == nil {
			pythonProg = path
		}

		timeSuffix := info.ModTime().Format("20060102150405")
		newName := fmt.Sprintf("%s-%s", name, timeSuffix)
		destTxtPath := filepath.Join(pcfg.TempLocation, fmt.Sprintf("%s.txt", newName))

		// Delete the core file after up to 2 attempts to process it.
		shouldDelete := time.Since(info.ModTime()) > time.Duration(pcfg.PostprocessIntervalSec)*time.Second

		pystackPath, pystackErr := exec.LookPath("pystack")
		gdbPath, gdbErr := exec.LookPath("gdb")

		if pystackErr != nil && gdbErr != nil {
			logger.Warnf(ctx, "Core dump analysis enabled but no analysis tools found. Please install pystack (recommended) or/and gdb into the runtime environment.")
		}

		if pystackErr == nil {
			args := []string{"core"}
			if len(pcfg.ExtraArgs) > 0 {
				args = append(args, pcfg.ExtraArgs...)
			} else {
				args = append(args, "--native-last")
			}
			args = append(args, corePath, pythonProg)

			logger.Printf(ctx, "Running pystack %s", strings.Join(args, " "))
			cmd := exec.CommandContext(ctx, pystackPath, args...)
			output, err := cmd.CombinedOutput()
			if err != nil {
				logger.Warnf(ctx, "pystack failed on %s: %v. Output:\n%s", name, err, string(output))
			} else {
				if err := os.WriteFile(destTxtPath, output, 0644); err != nil {
					logger.Warnf(ctx, "Failed to write pystack output to %s: %v", destTxtPath, err)
				}
				pystackSummary := createPystackSummary(string(output))
				logger.Errorf(ctx, "Full pystack coredump analysis saved to %s.txt\nExcerpt:\n%s", newName, pystackSummary)
				shouldDelete = true
			}
		}

		if gdbErr == nil {
			gdbArgs := []string{
				"-batch",
				"-ex", "set pagination off",
				"-ex", "set trace-commands on",
				"-ex", "info sharedlibrary",
				"-ex", "info proc mappings",
				"-ex", "info threads",
				"-ex", "thread",
				"-ex", "print $_siginfo",
				"-ex", "info registers",
				"-ex", "x/10i $pc",
				"-ex", "x/16gx $rsp",
				"-ex", "bt full",
				"-ex", "thread apply all bt full",
				pythonProg,
				corePath,
			}
			logger.Printf(ctx, "Running gdb on %s using %s", name, pythonProg)
			gdbCmd := exec.CommandContext(ctx, gdbPath, gdbArgs...)
			gdbOutput, err := gdbCmd.CombinedOutput()
			destGdbPath := filepath.Join(pcfg.TempLocation, fmt.Sprintf("%s.gdb.txt", newName))
			if err != nil {
				logger.Warnf(ctx, "gdb failed on %s: %v. Output:\n%s", name, err, string(gdbOutput))
			} else {
				if err := os.WriteFile(destGdbPath, gdbOutput, 0644); err != nil {
					logger.Warnf(ctx, "Failed to write gdb output to %s: %v", destGdbPath, err)
				}
				logger.Errorf(ctx, "Full GDB coredump analysis saved to %s.gdb.txt", newName)
				shouldDelete = true
			}
		}

		if shouldDelete {
			if err := os.Remove(corePath); err != nil {
				logger.Warnf(ctx, "Failed to delete core dump %s: %v", corePath, err)
			}
		}
	}
}

func extractGILThread(output string) string {
	lines := strings.Split(output, "\n")
	var result []string
	recording := false
	for _, line := range lines {
		trimmed := strings.TrimSpace(line)
		if strings.Contains(line, "Has the GIL") {
			recording = true
		}
		if recording {
			result = append(result, line)
			if trimmed == "" {
				break
			}
		}
	}
	if len(result) == 0 {
		return ""
	}
	return strings.Join(result, "\n")
}

func firstNLines(s string, n int) string {
	lines := strings.Split(s, "\n")
	if len(lines) <= n {
		return s
	}
	return strings.Join(lines[:n], "\n")
}

func createPystackSummary(output string) string {
	gilThreadTrace := extractGILThread(output)
	if gilThreadTrace != "" {
		return gilThreadTrace
	}
	return firstNLines(output, 100)
}

// cleanUpProfiler checks for and uploads any final profiler artifacts before container exit.
func cleanUpProfiler(ctx context.Context, logger *tools.Logger) {
	pcfg := getProfilerConfig(ctx)
	if pcfg == nil || !pcfg.Enabled {
		return
	}

	logger.Printf(ctx, "Running final profiler cleanup sweep and GCS sync...")

	// Execute all registered agent-specific cleanups
	for _, cb := range cleanupCallbacks {
		cb(ctx, logger)
	}

	if pcfg.GcsDestPath != "" && pcfg.GcloudAvailable {
		syncProfilesToGCS(ctx, logger, pcfg.BaseTempDir, pcfg.GcsDestPath)
	}
}
