package main

import (
	"context"
	"flag"
	"fmt"
	"strings"
	"time"

	admin "cloud.google.com/go/iam/admin/apiv1"
	"golang.org/x/oauth2/google"
	"google.golang.org/api/iterator"
	"google.golang.org/api/option"
	adminpb "google.golang.org/genproto/googleapis/iam/admin/v1"

	"go.skia.org/infra/go/auth"
	"go.skia.org/infra/go/common"
	"go.skia.org/infra/go/metrics2"
	"go.skia.org/infra/go/skerr"
	"go.skia.org/infra/go/sklog"
	"go.skia.org/infra/go/util"
)

const (
	//Metric names.
	saKeyExpirationMetric = "sa_key_expiration_s"
	livenessMetric        = "sa_keys_checker"
)

func main() {
	// Flags.
	cloudProjects := common.NewMultiStringFlag("cloud_project", nil, "Cloud projects in which this will scan all service accounts for expiring and expired keys.")
	promPort := flag.String("prom_port", ":20000", "Metrics service address (e.g., ':20000')")
	_ = flag.Bool("local", false, "Running locally if true. As opposed to in production.")
	pollPeriod := flag.Duration("poll_period", 5*time.Minute, "How often to check for expired service account keys.")

	common.InitWithMust("sa_keys_checker", common.PrometheusOpt(promPort), common.MetricsLoggingOpt())
	defer sklog.Flush()
	ctx := context.Background()

	if len(*cloudProjects) == 0 {
		sklog.Fatal("Must specify atleast one --cloud_project")
	}

	ts, err := google.DefaultTokenSource(ctx, auth.ScopeUserinfoEmail, auth.ScopeAllCloudAPIs)
	if err != nil {
		sklog.Fatalf("Could not create token source: %s", err)
	}

	// Pre-populate a map of cloud projects to the clients to use for them.
	clients := map[string]*admin.IamClient{}
	for _, p := range *cloudProjects {
		creds := &google.Credentials{
			ProjectID:   p,
			TokenSource: ts,
		}
		c, err := admin.NewIamClient(ctx, option.WithCredentials(creds))
		if err != nil {
			sklog.Fatalf("Failed to create IAM client: %s", err)
		}
		clients[p] = c
	}

	liveness := metrics2.NewLiveness(livenessMetric)
	oldMetrics := map[metrics2.Float64Metric]struct{}{}
	go util.RepeatCtx(ctx, *pollPeriod, func(ctx context.Context) {
		newMetrics, err := performChecks(ctx, clients, oldMetrics)
		if err != nil {
			sklog.Errorf("Error when checking for service account keys: %s", err)
		} else {
			liveness.Reset()
			oldMetrics = newMetrics
		}
	})

	select {}
}

func performChecks(ctx context.Context, clients map[string]*admin.IamClient, oldMetrics map[metrics2.Float64Metric]struct{}) (map[metrics2.Float64Metric]struct{}, error) {
	sklog.Info("-----------New round of checking service account keys expiration-----------")
	newMetrics := map[metrics2.Float64Metric]struct{}{}

	// * For each specified cloud project do the following:
	//   * Get list of all service accounts in that project and loop through them:
	//     * Get list of all keys that exist for those service accounts and loop through them:
	//       * Discard all auto-generated short lived keys.
	//       * Create and update a metric for the manually created keys.
	for p, c := range clients {
		saEmails := []string{}
		saIterator := c.ListServiceAccounts(ctx, &adminpb.ListServiceAccountsRequest{Name: fmt.Sprintf("projects/%s", p)})

		for {
			sa, err := saIterator.Next()
			if err == iterator.Done {
				break
			} else if err != nil {
				return nil, skerr.Wrap(err)
			}
			saEmails = append(saEmails, sa.Email)
		}

		for _, sa := range saEmails {
			serviceAccountPath := admin.IamServiceAccountPath(p, sa)
			resp, err := c.ListServiceAccountKeys(ctx, &adminpb.ListServiceAccountKeysRequest{
				Name: serviceAccountPath,
			})
			if err != nil {
				return nil, fmt.Errorf("Failed to list service account keys of %s: %s", sa, err)
			}
			for _, k := range resp.GetKeys() {
				processKey(k, newMetrics, sa, p)
			}
		}
	}
	sklog.Infof("Updated %d metrics", len(newMetrics))

	// Delete no longer used metrics.
	deleteUnusedMetrics(oldMetrics, newMetrics)

	return newMetrics, nil
}

// deleteUnusedMetrics finds all metrics that are in oldMetrics but not
// newMetrics and deletes them.
func deleteUnusedMetrics(oldMetrics, newMetrics map[metrics2.Float64Metric]struct{}) {
	deleteCount := 0
	for m := range oldMetrics {
		if _, ok := newMetrics[m]; !ok {
			if err := m.Delete(); err != nil {
				sklog.Errorf("Failed to delete metric: %s", err)
				// Add the metric to newMetrics so that we'll
				// have the chance to delete it again on the
				// next cycle.
				newMetrics[m] = struct{}{}
			} else {
				deleteCount += 1
			}
		}
	}
	sklog.Infof("Deleted %d old metrics", deleteCount)
}

// processKey determines whether the provided service account key is
// manually created. If it is then it updates a metric for that key.
func processKey(key *adminpb.ServiceAccountKey, metrics map[metrics2.Float64Metric]struct{}, sa, project string) {
	validAfter := time.Unix(key.GetValidAfterTime().Seconds, 0)
	validBefore := time.Unix(key.GetValidBeforeTime().Seconds, 0)
	duration := validBefore.Sub(validAfter)
	if duration > 21*24*time.Hour {
		// GCE seems to auto-generate keys with short
		// expirations. These do not show up on the UI.
		// Don't mess with them and only look at the longer
		// lived keys which we've created.

		duration = validBefore.Sub(time.Now())
		// Convert the long key name that looks like
		// "projects/skia-public/serviceAccounts/android-autoroll@skia-public.iam.gserviceaccount.com/keys/abc"
		// into the much more readable "abc".
		keyTokens := strings.Split(key.GetName(), "/")
		shortKeyName := keyTokens[len(keyTokens)-1]

		tags := map[string]string{
			"sa":      sa,
			"key":     shortKeyName,
			"project": project,
		}
		metric := metrics2.GetFloat64Metric(saKeyExpirationMetric, tags)
		metric.Update(duration.Seconds())
		metrics[metric] = struct{}{}
	}
}
