<commit_before>package main

import (
	"database/sql"
	"encoding/json"
	"errors"
	"fmt"
	"log"
	"strings"


	"github.com/satori/go.uuid"
)

type guidePost struct {
	input     chan treeRequest
	shutdown  chan bool
	conn      *sql.DB
	jbsv_stmt *sql.Stmt
	repo_stmt *sql.Stmt
	name_stmt *sql.Stmt
	node_stmt *sql.Stmt
	serv_stmt *sql.Stmt
	attr_stmt *sql.Stmt
	cthr_stmt *sql.Stmt
}

func (g *guidePost) run() {
	var err error

	log.Println("Prepare: guide/job-save")
	g.jbsv_stmt, err = g.conn.Prepare(`
INSERT INTO soma.jobs (
	job_id,
	job_status,
	job_result,
	job_type,
	repository_id,
	user_id,
	organizational_team_id,
	job)
SELECT	$1::uuid,
		$2::varchar,
		$3::varchar,
		$4::varchar,
		$5::uuid,
		$6::uuid,
		$7::uuid,
		$8::jsonb;`)
	if err != nil {
		log.Fatal("guide/job-save: ", err)
	}
	defer g.jbsv_stmt.Close()

	log.Println("Prepare: guide/repo-by-bucket")
	g.repo_stmt, err = g.conn.Prepare(`
SELECT	sb.repository_id,
		sr.repository_name
FROM	soma.buckets sb
JOIN    soma.repositories sr
ON		sb.repository_id = sr.repository_id
WHERE	sb.bucket_id = $1::uuid;`)
	if err != nil {
		log.Fatal("guide/repo-by-bucket: ", err)
	}
	defer g.repo_stmt.Close()

	log.Println("Prepare: guide/load-node-details")
	g.node_stmt, err = g.conn.Prepare(`
SELECT    sn.node_asset_id,
	      sn.node_name,
	      sn.organizational_team_id,
	      sn.server_id,
	      sn.node_online,
	      sn.node_deleted
FROM      soma.nodes sn
LEFT JOIN soma.node_bucket_assignment snba
ON        sn.node_id = snba.node_id
WHERE     sn.node_online = 'yes'
AND       sn.node_deleted = 'false'
AND       snba.node_id IS NULL
AND       sn.node_id = $1::uuid;`)
	if err != nil {
		log.Fatal("guide/load-node-details: ", err)
	}
	defer g.node_stmt.Close()

	log.Println("Prepare: guide/repo-by-id")
	g.name_stmt, err = g.conn.Prepare(`
SELECT repository_name
FROM   soma.repositories
WHERE  repository_id = $1::uuid;`)
	if err != nil {
		log.Fatal("guide/repo-by-id: ", err)
	}
	defer g.name_stmt.Close()

	log.Println("Prepare: guide/service-lookup")
	g.serv_stmt, err = g.conn.Prepare(`
SELECT stsp.service_property
FROM   soma.repositories sr
JOIN   soma.team_service_properties stsp
ON     sr.organizational_team_id = stsp.organizational_team_id
WHERE  sr.repository_id = $1::uuid
AND    stsp.service_property = $2::varchar
AND    sr.organizational_team_id = $3::uuid;`)
	if err != nil {
		log.Fatal("guide/service-lookup: ", err)
	}
	defer g.serv_stmt.Close()

	log.Println("Prepare: guide/populate-service-attributes")
	g.attr_stmt, err = g.conn.Prepare(`
SELECT stspv.service_property_attribute,
       stspv.value
FROM   soma.repositories sr
JOIN   soma.team_service_properties stsp
ON     sr.organizational_team_id = stsp.organizational_team_id
JOIN   soma.team_service_property_values stspv
ON     stsp.organizational_team_id = stspv.organizational_team_id
AND    stsp.service_property = stspv.service_property
WHERE  sr.repository_id = $1::uuid
AND    stsp.service_property = $2::varchar
AND    sr.organizational_team_id = $3::uuid;`)
	if err != nil {
		log.Fatal("guide/populate-service-attributes: ", err)
	}
	defer g.attr_stmt.Close()

	log.Println("Prepare: guide/capability-threshold-lookup")
	g.cthr_stmt, err = g.conn.Prepare(`
SELECT threshold_amount
FROM   soma.monitoring_capabilities
WHERE  capability_id = $1::uuid;`)
	if err != nil {
		log.Fatal("guide/capability-threshold-lookup: ", err)
	}
	defer g.cthr_stmt.Close()

runloop:
	for {
		select {
		case <-g.shutdown:
			break runloop
		case req := <-g.input:
			g.process(&req)
		}
	}
}

func (g *guidePost) process(q *treeRequest) {
	var (
		res                                sql.Result
		err                                error
		j                                  []byte
		repoId, repoName, keeper, bucketId string
		ndName, ndTeam, ndServer           string
		ndAsset                            int64
		ndOnline, ndDeleted                bool
	)
	result := somaResult{}

	switch q.Action {
	case "add_system_property_to_repository":
		fallthrough
	case "add_custom_property_to_repository":
		fallthrough
	case "add_oncall_property_to_repository":
		fallthrough
	case "add_service_property_to_repository":
		repoId = q.Repository.Repository.Id

	case "create_bucket":
		repoId = q.Bucket.Bucket.Repository
	case "add_system_property_to_bucket":
		fallthrough
	case "add_custom_property_to_bucket":
		fallthrough
	case "add_oncall_property_to_bucket":
		fallthrough
	case "add_service_property_to_bucket":
		bucketId = q.Bucket.Bucket.Id

	case "create_group":
		fallthrough
	case "add_group_to_group":
		fallthrough
	case "add_cluster_to_group":
		fallthrough
	case "add_node_to_group":
		fallthrough
	case "add_system_property_to_group":
		fallthrough
	case "add_custom_property_to_group":
		fallthrough
	case "add_oncall_property_to_group":
		fallthrough
	case "add_service_property_to_group":
		bucketId = q.Group.Group.BucketId

	case "add_node_to_cluster":
		if q.Cluster.Cluster.BucketId != q.Cluster.Cluster.Members[0].Config.BucketId {
			panic("This should not happen.")
		}
		fallthrough
	case "create_cluster":
		fallthrough
	case "add_system_property_to_cluster":
		fallthrough
	case "add_custom_property_to_cluster":
		fallthrough
	case "add_oncall_property_to_cluster":
		fallthrough
	case "add_service_property_to_cluster":
		bucketId = q.Cluster.Cluster.BucketId

	case "add_check_to_repository":
		fallthrough
	case "add_check_to_bucket":
		fallthrough
	case "add_check_to_group":
		fallthrough
	case "add_check_to_cluster":
		fallthrough
	case "add_check_to_node":
		repoId = q.CheckConfig.CheckConfig.RepositoryId

	case "assign_node":
		if err = g.node_stmt.QueryRow(q.Node.Node.Id).Scan(
			&ndAsset,
			&ndName,
			&ndTeam,
			&ndServer,
			&ndOnline,
			&ndDeleted,
		); err != nil {
			if err == sql.ErrNoRows {
				result.SetNotFound()
			} else {
				_ = result.SetRequestError(err)
			}
			q.reply <- result
			return
		}

		q.Node.Node.AssetId = uint64(ndAsset)
		q.Node.Node.Name = ndName
		q.Node.Node.Team = ndTeam
		q.Node.Node.Server = ndServer
		q.Node.Node.IsOnline = ndOnline
		q.Node.Node.IsDeleted = ndDeleted
		fallthrough
	case "add_system_property_to_node":
		fallthrough
	case "add_custom_property_to_node":
		fallthrough
	case "add_oncall_property_to_node":
		fallthrough
	case "add_service_property_to_node":
		repoId = q.Node.Node.Config.RepositoryId
		bucketId = q.Node.Node.Config.BucketId

	default:
		log.Printf("R: unimplemented guidepost/%s", q.Action)
		result.SetNotImplemented()
		q.reply <- result
		return
	}

	// lookup repository by bucket
	if bucketId != "" {
		if err = g.repo_stmt.QueryRow(bucketId).Scan(&repoId, &repoName); err != nil {
			if err == sql.ErrNoRows {
				result.SetNotFound()
			} else {
				_ = result.SetRequestError(err)
			}
			q.reply <- result<commit_msg>Fix: nil pointer dereference ProtoNode.Config<commit_after>package main

import (
	"database/sql"
	"encoding/json"
	"errors"
	"fmt"
	"log"
	"strings"


	"github.com/satori/go.uuid"
)

type guidePost struct {
	input     chan treeRequest
	shutdown  chan bool
	conn      *sql.DB
	jbsv_stmt *sql.Stmt
	repo_stmt *sql.Stmt
	name_stmt *sql.Stmt
	node_stmt *sql.Stmt
	serv_stmt *sql.Stmt
	attr_stmt *sql.Stmt
	cthr_stmt *sql.Stmt
}

func (g *guidePost) run() {
	var err error

	log.Println("Prepare: guide/job-save")
	g.jbsv_stmt, err = g.conn.Prepare(`
INSERT INTO soma.jobs (
	job_id,
	job_status,
	job_result,
	job_type,
	repository_id,
	user_id,
	organizational_team_id,
	job)
SELECT	$1::uuid,
		$2::varchar,
		$3::varchar,
		$4::varchar,
		$5::uuid,
		$6::uuid,
		$7::uuid,
		$8::jsonb;`)
	if err != nil {
		log.Fatal("guide/job-save: ", err)
	}
	defer g.jbsv_stmt.Close()

	log.Println("Prepare: guide/repo-by-bucket")
	g.repo_stmt, err = g.conn.Prepare(`
SELECT	sb.repository_id,
		sr.repository_name
FROM	soma.buckets sb
JOIN    soma.repositories sr
ON		sb.repository_id = sr.repository_id
WHERE	sb.bucket_id = $1::uuid;`)
	if err != nil {
		log.Fatal("guide/repo-by-bucket: ", err)
	}
	defer g.repo_stmt.Close()

	log.Println("Prepare: guide/load-node-details")
	g.node_stmt, err = g.conn.Prepare(`
SELECT    sn.node_asset_id,
	      sn.node_name,
	      sn.organizational_team_id,
	      sn.server_id,
	      sn.node_online,
	      sn.node_deleted
FROM      soma.nodes sn
LEFT JOIN soma.node_bucket_assignment snba
ON        sn.node_id = snba.node_id
WHERE     sn.node_online = 'yes'
AND       sn.node_deleted = 'false'
AND       snba.node_id IS NULL
AND       sn.node_id = $1::uuid;`)
	if err != nil {
		log.Fatal("guide/load-node-details: ", err)
	}
	defer g.node_stmt.Close()

	log.Println("Prepare: guide/repo-by-id")
	g.name_stmt, err = g.conn.Prepare(`
SELECT repository_name
FROM   soma.repositories
WHERE  repository_id = $1::uuid;`)
	if err != nil {
		log.Fatal("guide/repo-by-id: ", err)
	}
	defer g.name_stmt.Close()

	log.Println("Prepare: guide/service-lookup")
	g.serv_stmt, err = g.conn.Prepare(`
SELECT stsp.service_property
FROM   soma.repositories sr
JOIN   soma.team_service_properties stsp
ON     sr.organizational_team_id = stsp.organizational_team_id
WHERE  sr.repository_id = $1::uuid
AND    stsp.service_property = $2::varchar
AND    sr.organizational_team_id = $3::uuid;`)
	if err != nil {
		log.Fatal("guide/service-lookup: ", err)
	}
	defer g.serv_stmt.Close()

	log.Println("Prepare: guide/populate-service-attributes")
	g.attr_stmt, err = g.conn.Prepare(`
SELECT stspv.service_property_attribute,
       stspv.value
FROM   soma.repositories sr
JOIN   soma.team_service_properties stsp
ON     sr.organizational_team_id = stsp.organizational_team_id
JOIN   soma.team_service_property_values stspv
ON     stsp.organizational_team_id = stspv.organizational_team_id
AND    stsp.service_property = stspv.service_property
WHERE  sr.repository_id = $1::uuid
AND    stsp.service_property = $2::varchar
AND    sr.organizational_team_id = $3::uuid;`)
	if err != nil {
		log.Fatal("guide/populate-service-attributes: ", err)
	}
	defer g.attr_stmt.Close()

	log.Println("Prepare: guide/capability-threshold-lookup")
	g.cthr_stmt, err = g.conn.Prepare(`
SELECT threshold_amount
FROM   soma.monitoring_capabilities
WHERE  capability_id = $1::uuid;`)
	if err != nil {
		log.Fatal("guide/capability-threshold-lookup: ", err)
	}
	defer g.cthr_stmt.Close()

runloop:
	for {
		select {
		case <-g.shutdown:
			break runloop
		case req := <-g.input:
			g.process(&req)
		}
	}
}

func (g *guidePost) process(q *treeRequest) {
	var (
		res                                sql.Result
		err                                error
		j                                  []byte
		repoId, repoName, keeper, bucketId string
		ndName, ndTeam, ndServer           string
		ndAsset                            int64
		ndOnline, ndDeleted                bool
	)
	result := somaResult{}

	switch q.Action {
	case "add_system_property_to_repository":
		fallthrough
	case "add_custom_property_to_repository":
		fallthrough
	case "add_oncall_property_to_repository":
		fallthrough
	case "add_service_property_to_repository":
		repoId = q.Repository.Repository.Id

	case "create_bucket":
		repoId = q.Bucket.Bucket.Repository
	case "add_system_property_to_bucket":
		fallthrough
	case "add_custom_property_to_bucket":
		fallthrough
	case "add_oncall_property_to_bucket":
		fallthrough
	case "add_service_property_to_bucket":
		bucketId = q.Bucket.Bucket.Id

	case "create_group":
		fallthrough
	case "add_group_to_group":
		fallthrough
	case "add_cluster_to_group":
		fallthrough
	case "add_node_to_group":
		fallthrough
	case "add_system_property_to_group":
		fallthrough
	case "add_custom_property_to_group":
		fallthrough
	case "add_oncall_property_to_group":
		fallthrough
	case "add_service_property_to_group":
		bucketId = q.Group.Group.BucketId

	case "add_node_to_cluster":
		if q.Cluster.Cluster.BucketId != q.Cluster.Cluster.Members[0].Config.BucketId {
			panic("This should not happen.")
		}
		fallthrough
	case "create_cluster":
		fallthrough
	case "add_system_property_to_cluster":
		fallthrough
	case "add_custom_property_to_cluster":
		fallthrough
	case "add_oncall_property_to_cluster":
		fallthrough
	case "add_service_property_to_cluster":
		bucketId = q.Cluster.Cluster.BucketId

	case "add_check_to_repository":
		fallthrough
	case "add_check_to_bucket":
		fallthrough
	case "add_check_to_group":
		fallthrough
	case "add_check_to_cluster":
		fallthrough
	case "add_check_to_node":
		repoId = q.CheckConfig.CheckConfig.RepositoryId

	case "assign_node":
		if err = g.node_stmt.QueryRow(q.Node.Node.Id).Scan(
			&ndAsset,
			&ndName,
			&ndTeam,
			&ndServer,
			&ndOnline,
			&ndDeleted,
		); err != nil {
			if err == sql.ErrNoRows {
				result.SetNotFound()
			} else {
				_ = result.SetRequestError(err)
			}
			q.reply <- result
			return
		}

		q.Node.Node.AssetId = uint64(ndAsset)
		q.Node.Node.Name = ndName
		q.Node.Node.Team = ndTeam
		q.Node.Node.Server = ndServer
		q.Node.Node.IsOnline = ndOnline
		q.Node.Node.IsDeleted = ndDeleted
		fallthrough
	case "add_system_property_to_node":
		fallthrough
	case "add_custom_property_to_node":
		fallthrough
	case "add_oncall_property_to_node":
		fallthrough
	case "add_service_property_to_node":
		if q.Node.Node.Config == nil {
			_ = result.SetRequestError(fmt.Errorf("NodeConfig subobject missing"))
			q.reply <- result
			return
		}
		repoId = q.Node.Node.Config.RepositoryId
		bucketId = q.Node.Node.Config.BucketId

	default:
		log.Printf("R: unimplemented guidepost/%s", q.Action)
		result.SetNotImplemented()
		q.reply <- result
		return
	}

	// lookup repository by bucket
	if bucketId != "" {
		if err = g.repo_stmt.QueryRow(bucketId).Scan(&repoId, &repoName); err != nil {
			if err == sql.ErrNoRows {
				result.SetNotFound()
			} else {
				_ = result.SetRequestError(err)
			}
			q.reply <- result
{'fraction_non_alphanumeric': 0.11373203658005517, 'fraction_numerical': 0.0033386558281318043, 'mean_word_length': 3.666102268879106, 'pattern_counts': {'":': 66, '<': 14, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3190213', 'n_tokens_mistral': 5490, 'n_tokens_neox': 5112, 'n_words': 956}