package config

import (
	"errors"
	"fmt"
)

// Resources represents all the resources we need for a deployment
type Resources struct {
	AuditTableName      string `default:"malachai-audit-production"`
	MalachaiAdminGroups []string
	// list of groups that can create private services
	MalachaiAutomationGroups      []string
	CapabilitiesTable             string `default:"malachai-capabilities-production"`
	CapabilitiesTableArn          string `default:"arn:aws:dynamodb:us-west-2:180116294062:table/malachai-capabilities-production"`
	CapabilitiesLambdaRoleArn     string
	CloudWatchReporterRoleArn     string
	MalachaiGQLUrl                string
	Region                        string `default:"us-west-2"`
	ServicesTable                 string `default:"malachai-services-production"`
	ServicesTableArn              string `default:"arn:aws:dynamodb:us-west-2:180116294062:table/malachai-services-production"`
	DiscoveryTable                string `default:"malachai-discovery-production"`
	DiscoveryTableArn             string `default:"arn:aws:dynamodb:us-west-2:180116294062:table/malachai-discovery-production"`
	GuardianEndpoint              string
	CalleeCapabilitiesTopicARN    string
	MalachaiWhitelistRoleName     string
	PubkeyInvalidationTopicARN    string `default:"arn:aws:sns:us-west-2:180116294062:pubkey-invalidations-production"`
	TestUserArn                   string `default:"arn:aws:iam::289423984879:user/sse-admin-testing"`
	SandstormKMSKeyID             string `default:"alias/sandstorm-production"`
	SandstormSecretsTableName     string `default:"sandstorm-production"`
	SandstormSecretsTableArn      string `default:"arn:aws:dynamodb:us-west-2:734326455073:table/sandstorm-production"`
	SandstormSecretsAuditTableArn string `default:"arn:aws:dynamodb:us-west-2:734326455073:table/sandstorm-production_audit"`
	SandstormAuxPolicyArn         string `default:"arn:aws:iam::734326455073:policy/sandstorm/production/aux_policy/sandstorm-agent-production-aux"`
	SandstormRoleOwnerTableName   string `default:"sandstorm-production_role_owners"`
	SandstormNamespaceTableArn    string `default:"arn:aws:dynamodb:us-west-2:734326455073:table/sandstorm-production_namespaces"`
	SandstormTopicArn             string
	SandstormRoleArn              string `default:"arn:aws:iam::734326455073:role/terraform/production/role/malachai00049650eec2b974926bf9d0b3"`
	TestServicePrefix             string
	Environment                   string `default:"production"`
	RootUserArn                   string `default:"arn:aws:iam::180116294062:root"`
	RoleArn                       string
	AuditTableReadWriteRoleArn    string
	AuditTableReadRoleArn         string
	MalachaiAccountID             string `default:"180116294062"`
	FirehoseDeliveryStreamName    string
	FirehoseLogsS3BucketName      string
	AuxiliaryRoleArn              string `default:"arn:aws:iam::180116294062:role/malachai/auxiliary/malachai-services-read-only-production"`
	FirehoseLoggerRoleArn         string `default:"arn:aws:iam::180116294062:role/malachai/auxiliary/malachai-services-firehose-logger-production"`
	CORSAllowedHeaders            []string
	CORSAllowedOrigins            []string
	CORSMaxAge                    string
	InventoryTableName            string `default:"malachai-inventory-production"`
	InventoryTableArn             string `default:"arn:aws:dynamodb:us-west-2:180116294062:table/malachai-inventory-production"`
	AthenaQueryRoleArn            string
	AthenaTestResultBucketName    string
	ServicePaginationRedisURL     string `default:"redis://service-pagination.hmae4k.0001.usw2.cache.amazonaws.com:6379/1"`
	StatsWriterRoleArn            string
	AccessRequestTableName        string
	TeamNotificationsTableName    string
	AccessRequestWriteRoleArn     string
	SyncServiceIndexFuncName      string

	// sync service lambda pushes the set of all registered service names in
	// lexicographical order to redis
	SyncServiceLockTableName string
	SyncServiceLockName      string

	// service-ro-mgmt lambda reads all of the whitelisted ARNs for all
	// registered services and ensures those accounts can assume the sharded
	// services read only roles
	ServicesReadOnlyLockTableName  string
	ServicesReadOnlyLockName       string
	ServicesReadOnlyRoleCount      int
	ServicesReadOnlyRoleNamePrefix string
	ServicesReadOnlyMgmtLambdaName string
}

// getResourcesForEnvironment returns resource names for env
func getResourcesForEnvironment(env string, sandstormAccountID string) *Resources {
	return &Resources{
		MalachaiAdminGroups:           []string{"team-sse"},
		MalachaiAutomationGroups:      []string{"team-sse-automation"},
		AuditTableName:                "malachai-audit-table-" + env,
		CapabilitiesTable:             "malachai-capabilities-" + env,
		Region:                        "us-west-2",
		ServicesTable:                 "malachai-services-" + env,
		DiscoveryTable:                "malachai-discovery-" + env,
		SandstormKMSKeyID:             "alias/sandstorm-" + env,
		SandstormSecretsTableName:     "sandstorm-" + env,
		InventoryTableName:            "malachai-inventory-" + env,
		Environment:                   env,
		SandstormSecretsTableArn:      fmt.Sprintf("arn:aws:dynamodb:us-west-2:%s:table/sandstorm-%s", sandstormAccountID, env),
		SandstormSecretsAuditTableArn: fmt.Sprintf("arn:aws:dynamodb:us-west-2:%s:table/sandstorm-%s_audit", sandstormAccountID, env),
		SandstormNamespaceTableArn:    fmt.Sprintf("arn:aws:dynamodb:us-west-2:%s:table/sandstorm-%s_namespaces", sandstormAccountID, env),
		SandstormRoleOwnerTableName:   "sandstorm-" + env + "_role_owners",
		SandstormAuxPolicyArn:         fmt.Sprintf("arn:aws:iam::%s:policy/sandstorm/%s/aux_policy/sandstorm-agent-%s-aux", sandstormAccountID, env, env),
		SandstormTopicArn:             fmt.Sprintf("arn:aws:sns:us-west-2:%s:sandstorm-%s", sandstormAccountID, env),
		RoleArn:                       "arn:aws:iam::289423984879:role/malachai-admin-role-" + env,
		FirehoseDeliveryStreamName:    "firehose-to-s3-logs-bucket-delivery-stream-" + env,
		FirehoseLogsS3BucketName:      "malachai-firehose-logs-" + env,
		MalachaiWhitelistRoleName:     "malachai-services-read-only-" + env,
		AthenaTestResultBucketName:    fmt.Sprintf("malachai-athena-query-results-%s/", env),
		CORSAllowedHeaders: []string{
			"Authorization",
			"Content-Type",
		},
		CORSMaxAge:                     "5h",
		TestServicePrefix:              "malachai-itest--",
		TeamNotificationsTableName:     "notification-identifiers-" + env,
		AccessRequestTableName:         "access-request-" + env,
		SyncServiceIndexFuncName:       "malachai-" + env + "-sync-service-index",
		SyncServiceLockTableName:       "malachai-service-sync-lock-" + env,
		SyncServiceLockName:            "malachai-service-sync-lock-" + env,
		ServicesReadOnlyLockTableName:  "malachai-service-ro-mgmt-lock-" + env,
		ServicesReadOnlyLockName:       "malachai-service-ro-mgmt-lock-" + env,
		ServicesReadOnlyRoleCount:      20,
		ServicesReadOnlyRoleNamePrefix: "malachai-services-read-only-shard",
		ServicesReadOnlyMgmtLambdaName: "malachai-" + env + "-services-ro-mgmt",
	}
}

// GetResourcesForTesting returns resources for testing
func GetResourcesForTesting() (res *Resources) {
	sandstormAccountID := "505345203727"
	res = getResourcesForEnvironment("testing", sandstormAccountID)
	res.CalleeCapabilitiesTopicARN = "arn:aws:sns:us-west-2:289423984879:capabilities-callee"
	res.CapabilitiesLambdaRoleArn = "arn:aws:iam::289423984879:role/malachai-capabilities-lambda-testing"
	res.CloudWatchReporterRoleArn = "arn:aws:iam::289423984879:role/malachai/testing/services-aux/malachai-cloudwatch-reporting-testing"
	res.MalachaiGQLUrl = "https://malachai-api-staging.internal.justin.tv"
	res.PubkeyInvalidationTopicARN = "arn:aws:sns:us-west-2:289423984879:pubkey-invalidations-testing"
	res.CapabilitiesTableArn = "arn:aws:dynamodb:us-west-2:289423984879:table/malachai-capabilities-testing"
	res.ServicesTableArn = "arn:aws:dynamodb:us-west-2:289423984879:table/malachai-services-testing"
	res.DiscoveryTableArn = "arn:aws:dynamodb:us-west-2:289423984879:table/malachai-discovery-testing"
	res.TestUserArn = "arn:aws:iam::289423984879:user/sse-admin-testing"
	res.SandstormRoleArn = fmt.Sprintf("arn:aws:iam::%s:role/terraform/testing/role/malachai20171129211408766800000001", sandstormAccountID)
	res.RootUserArn = "arn:aws:iam::289423984879:root"
	res.AuditTableReadWriteRoleArn = "arn:aws:iam::289423984879:role/malachai-audit-table-admin-testing"
	res.AuditTableReadRoleArn = "arn:aws:iam::289423984879:role/malachai-audit-table-read-testing"
	res.MalachaiAccountID = "289423984879"
	res.AuxiliaryRoleArn = "arn:aws:iam::289423984879:role/malachai/auxiliary/malachai-services-read-only-testing"
	res.FirehoseLoggerRoleArn = "arn:aws:iam::289423984879:role/malachai/auxiliary/malachai-services-firehose-logger-testing"
	res.GuardianEndpoint = "https://guardian-staging.dev.us-west2.justin.tv"
	res.CORSAllowedOrigins = []string{
		"https://dashboard-v2-staging.internal.justin.tv",
	}
	res.InventoryTableArn = "arn:aws:dynamodb:us-west-2:289423984879:table/malachai-inventory-testing"
	res.ServicePaginationRedisURL = "redis://service-pagination.5is4u1.0001.usw2.cache.amazonaws.com:6379/1"
	res.StatsWriterRoleArn = "arn:aws:iam::289423984879:role/malachai-cloudwatch-reporting-testing"
	res.AthenaQueryRoleArn = "arn:aws:iam::289423984879:role/malachai/testing/malachai-athena-query-execution-testing"
	res.AccessRequestWriteRoleArn = "arn:aws:iam::997758849083:role/access-request-write-testing"
	return
}

// GetResourcesForProduction returns resources for production
// The management service needs to set the CalleeCapabilitiesTopicARN, which is
// unique to each callee service.
func GetResourcesForProduction() (res *Resources) {
	sandstormAccountID := "734326455073"
	res = getResourcesForEnvironment("production", sandstormAccountID)
	res.AuditTableReadWriteRoleArn = "arn:aws:iam::180116294062:role/malachai-audit-table-admin-production"
	res.AuditTableReadRoleArn = "arn:aws:iam::180116294062:role/malachai-audit-table-read-production"
	res.CalleeCapabilitiesTopicARN = "arn:aws:sns:us-west-2:180116294062:capabilities-callee"
	res.MalachaiGQLUrl = "https://malachai-api.internal.justin.tv"
	res.PubkeyInvalidationTopicARN = "arn:aws:sns:us-west-2:180116294062:pubkey-invalidations-production"
	res.CapabilitiesTableArn = "arn:aws:dynamodb:us-west-2:180116294062:table/malachai-capabilities-production"
	res.CapabilitiesLambdaRoleArn = "arn:aws:iam::180116294062:role/malachai-capabilities-lambda-production"
	res.CloudWatchReporterRoleArn = "arn:aws:iam::180116294062:role/malachai/production/services-aux/malachai-cloudwatch-reporting-production"
	res.SandstormRoleArn = fmt.Sprintf("arn:aws:iam::%s:role/terraform/production/role/malachai00049650eec2b974926bf9d0b3", sandstormAccountID)
	res.ServicesTableArn = "arn:aws:dynamodb:us-west-2:180116294062:table/malachai-services-production"
	res.DiscoveryTableArn = "arn:aws:dynamodb:us-west-2:180116294062:table/malachai-discovery-production"
	res.RootUserArn = "arn:aws:iam::180116294062:root"
	res.MalachaiAccountID = "180116294062"
	res.AuxiliaryRoleArn = "arn:aws:iam::180116294062:role/malachai/auxiliary/malachai-services-read-only-production"
	res.RoleArn = "arn:aws:iam::180116294062:role/malachai-admin-role-production"
	res.FirehoseLoggerRoleArn = "arn:aws:iam::180116294062:role/malachai/auxiliary/malachai-services-firehose-logger-production"
	res.GuardianEndpoint = "https://guardian.internal.justin.tv"
	res.CORSAllowedOrigins = []string{
		"https://dashboard-v2.internal.justin.tv",
	}
	res.InventoryTableArn = "arn:aws:dynamodb:us-west-2:180116294062:table/malachai-inventory-production"
	res.ServicePaginationRedisURL = "redis://service-pagination.hmae4k.0001.usw2.cache.amazonaws.com:6379/1"
	res.StatsWriterRoleArn = "arn:aws:iam::180116294062:role/malachai-cloudwatch-reporting-production"
	res.AthenaQueryRoleArn = "arn:aws:iam::180116294062:role/malachai/testing/malachai-athena-query-execution-production"
	res.AccessRequestWriteRoleArn = "arn:aws:iam::064097594731:role/access-request-write-production"
	return
}

// GetResources returns the resources for an environment string
func GetResources(environment string) (res *Resources, err error) {
	switch environment {
	case "testing":
		res = GetResourcesForTesting()
	case "production":
		res = GetResourcesForProduction()
	default:
		err = errors.New("environment must be 'testing' or 'production'")
	}
	return
}
