// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package netstack

import (
	"context"
	"crypto/rand"
	"encoding/base64"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"path/filepath"
	"reflect"
	"strconv"
	"sync/atomic"
	"syscall/zx"
	"syscall/zx/fidl"
	"time"

	networking_metrics "networking_metrics_golib"

	"go.fuchsia.dev/fuchsia/src/connectivity/network/netstack/dns"
	"go.fuchsia.dev/fuchsia/src/connectivity/network/netstack/filter"
	"go.fuchsia.dev/fuchsia/src/connectivity/network/netstack/pprof"

	"go.fuchsia.dev/fuchsia/src/lib/component"
	syslog "go.fuchsia.dev/fuchsia/src/lib/syslog/go"

	"fidl/fuchsia/cobalt"
	"fidl/fuchsia/device"
	"fidl/fuchsia/net/interfaces"
	"fidl/fuchsia/net/neighbor"
	"fidl/fuchsia/net/routes"
	"fidl/fuchsia/net/stack"
	"fidl/fuchsia/netstack"
	"fidl/fuchsia/posix/socket"
	"fidl/fuchsia/stash"

	glog "gvisor.dev/gvisor/pkg/log"
	"gvisor.dev/gvisor/pkg/tcpip"
	"gvisor.dev/gvisor/pkg/tcpip/header"
	"gvisor.dev/gvisor/pkg/tcpip/link/sniffer"
	"gvisor.dev/gvisor/pkg/tcpip/network/arp"
	"gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
	"gvisor.dev/gvisor/pkg/tcpip/network/ipv6"
	tcpipstack "gvisor.dev/gvisor/pkg/tcpip/stack"
	"gvisor.dev/gvisor/pkg/tcpip/transport/icmp"
	"gvisor.dev/gvisor/pkg/tcpip/transport/tcp"
	"gvisor.dev/gvisor/pkg/tcpip/transport/udp"
)

const (
	// stashStoreIdentificationName is the name used to identify this (netstack)
	// component to the fuchsia.stash.SecureStore service.
	stashStoreIdentificationName = "netstack-stash"

	// opaqueIIDSecretKeyName is the name of the key used to access the secret key
	// for opaque IIDs from the secure stash store.
	opaqueIIDSecretKeyName = "opaque-iid-secret-key"

	// dadTransmits is the number of consecutive NDP Neighbor Solicitation
	// messages sent while performing Duplicate Address Detection on a IPv6
	// tentative address.
	//
	// As per RFC 4862 section 5.1, 1 is the default number of messages to send.
	dadTransmits = 1

	// dadRetransmitTimer is the time between retransmissions of NDP Neighbor
	// Solicitation messages to a neighbor.
	//
	// As per RFC 4861 section 10, 1s is the default time between retransmissions.
	dadRetransmitTimer = time.Second

	// maxRtrSolicitations is the maximum number of Router Solicitation messages
	// to send when a NIC becomes enabled.
	//
	// As per RFC 4861 section 10, 3 is the default number of messages.
	maxRtrSolicitations = 3

	// rtrSolicitationInterval is the amount of time between sending Router
	// Solicitation messages.
	//
	// As per RFC 4861 section 10, 4s is the default time between transmissions.
	rtrSolicitationInterval = 4 * time.Second

	// maxRtrSolicitationDelay is the maximum amount of time to wait before
	// sending the first Router Solicitation message.
	//
	// As per RFC 4861 section 10, 1s is the default maximum time to wait.
	maxRtrSolicitationDelay = time.Second

	// autoGenAddressConflictRetries is the maximum number of times to attempt
	// SLAAC address regeneration in response to DAD conflicts.
	//
	// As per RFC 7217 section, 3 is the default maximum number of retries.
	autoGenAddressConflictRetries = 3

	// maxTempAddrValidLifetime is the maximum amount of time a temporary SLAAC
	// address may be valid for from creation.
	//
	// As per RFC 4941 section 5, 7 days is the default max valid lifetime.
	maxTempAddrValidLifetime = 7 * 24 * time.Hour

	// maxTempAddrPreferredLifetime is the maximum amount of time a temporary
	// SLAAC address may be preferred for from creation.
	//
	// As per RFC 4941 section 5, 1 day is the default max preferred lifetime.
	maxTempAddrPreferredLifetime = 24 * time.Hour

	// regenAdvanceDuration is duration before the deprecation of a temporary
	// address when a new address will be generated.
	//
	// As per RFC 4941 section 5, 5s is the default duration. We make the duration
	// the default duration plus the maximum amount of time for an address to
	// resolve DAD if all but the last regeneration attempts fail. This is to
	// guarantee that if a new address is generated, it will be assigned for at
	// least 5s before the original address is deprecated.
	regenAdvanceDuration = 5*time.Second + dadTransmits*dadRetransmitTimer*(1+autoGenAddressConflictRetries)
)

type atomicBool uint32

// IsBoolFlag implements flag.boolFlag.IsBoolFlag.
//
// See the flag.Value documentation for more information.
func (*atomicBool) IsBoolFlag() bool {
	return true
}

// Set implements flag.Value.Set.
func (a *atomicBool) Set(s string) error {
	v, err := strconv.ParseBool(s)
	if err != nil {
		return err
	}
	var val uint32
	if v {
		val = 1
	}
	atomic.StoreUint32((*uint32)(a), val)
	return nil
}

// String implements flag.Value.String.
func (a *atomicBool) String() string {
	return strconv.FormatBool(atomic.LoadUint32((*uint32)(a)) != 0)
}

func init() {
	// As of this writing the default is 1.
	atomic.StoreUint32(&sniffer.LogPackets, 0)
}

type glogEmitter struct{}

func (*glogEmitter) Emit(depth int, level glog.Level, timestamp time.Time, format string, v ...interface{}) {
	switch level {
	case glog.Warning:
		syslog.Warnf(format, v...)
	case glog.Info:
		syslog.Infof(format, v...)
	case glog.Debug:
		syslog.Debugf(format, v...)
	}
}

func Main() {
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	logLevel := syslog.InfoLevel

	flags := flag.NewFlagSet(os.Args[0], flag.ContinueOnError)
	flags.Var((*atomicBool)(&sniffer.LogPackets), "log-packets", "enable packet logging")
	flags.Var(&logLevel, "verbosity", "set the logging verbosity")

	var cobaltClientTimerPeriod, socketStatsTimerPeriod time.Duration
	flags.DurationVar(&cobaltClientTimerPeriod, "cobalt-scheduling-interval", time.Minute, "set the interval at which metrics will be sent to Cobalt")
	flags.DurationVar(&socketStatsTimerPeriod, "socket-stats-sampling-interval", time.Minute, "set the interval at which socket stats will be sampled")
	if err := flags.Parse(os.Args[1:]); err != nil {
		panic(err)
	}

	appCtx := component.NewContextFromStartupInfo()

	s, err := syslog.ConnectToLogger(appCtx.Connector())
	if err != nil {
		panic(fmt.Sprintf("failed to connect to syslog: %s", err))
	}
	l, err := syslog.NewLogger(syslog.LogInitOptions{
		LogLevel:                      logLevel,
		MinSeverityForFileAndLineInfo: logLevel,
		Socket:                        s,
		Tags:                          []string{"netstack"},
	})
	if err != nil {
		panic(err)
	}
	syslog.SetDefaultLogger(l)
	log.SetOutput(&syslog.Writer{Logger: l})
	log.SetFlags(log.Lshortfile)
	glog.SetTarget(&glogEmitter{})

	secretKeyForOpaqueIID, err := getSecretKeyForOpaqueIID(appCtx)
	if err != nil {
		panic(fmt.Sprintf("failed to get secret key for opaque IIDs: %s", err))
	}

	tempIIDSeed, err := newSecretKey(header.IIDSize)
	if err != nil {
		panic(fmt.Sprintf("failed to get temp IID seed: %s", err))
	}

	ndpDisp := newNDPDispatcher()
	var nudDisp nudDispatcher

	stk := tcpipstack.New(tcpipstack.Options{
		NetworkProtocols: []tcpipstack.NetworkProtocolFactory{
			arp.NewProtocol,
			ipv4.NewProtocol,
			ipv6.NewProtocolWithOptions(ipv6.Options{
				NDPConfigs: ipv6.NDPConfigurations{
					DupAddrDetectTransmits:        dadTransmits,
					RetransmitTimer:               dadRetransmitTimer,
					MaxRtrSolicitations:           maxRtrSolicitations,
					RtrSolicitationInterval:       rtrSolicitationInterval,
					MaxRtrSolicitationDelay:       maxRtrSolicitationDelay,
					HandleRAs:                     true,
					DiscoverDefaultRouters:        true,
					DiscoverOnLinkPrefixes:        true,
					AutoGenGlobalAddresses:        true,
					AutoGenAddressConflictRetries: autoGenAddressConflictRetries,
					AutoGenTempGlobalAddresses:    true,
					MaxTempAddrValidLifetime:      maxTempAddrValidLifetime,
					MaxTempAddrPreferredLifetime:  maxTempAddrPreferredLifetime,
					RegenAdvanceDuration:          regenAdvanceDuration,
				},
				AutoGenIPv6LinkLocal: true,
				NDPDisp:              ndpDisp,
				OpaqueIIDOpts: ipv6.OpaqueInterfaceIdentifierOptions{
					NICNameFromID: func(nicID tcpip.NICID, nicName string) string {
						// As of writing, Netstack creates NICs with names so we return the name
						// the NIC was created with. Just in case, we have a default NIC name
						// format for NICs that were not created with a name.
						if nicName != "" {
							return nicName
						}
						return fmt.Sprintf("opaqueIIDNIC%d", nicID)
					},
					SecretKey: secretKeyForOpaqueIID,
				},
				TempIIDSeed: tempIIDSeed,
			}),
		},
		TransportProtocols: []tcpipstack.TransportProtocolFactory{
			icmp.NewProtocol4,
			icmp.NewProtocol6,
			tcp.NewProtocol,
			udp.NewProtocol,
		},
		HandleLocal: true,

		// Enable use of the neighbor cache as part of the staged rollout
		// (fxbug.dev/61723) for Neighbor Unreachability Detection. This enables
		// inspection and modification of entries in the neighbor cache.
		UseNeighborCache: true,
		NUDDisp:          &nudDisp,

		// Raw sockets are typically used for implementing custom protocols. We intend
		// to support custom protocols through structured FIDL APIs in the future, so
		// disable raw sockets to prevent them from accidentally becoming load-bearing.
		RawFactory: nil,
	})

	delayEnabled := tcpip.TCPDelayEnabled(true)
	sackEnabled := tcpip.TCPSACKEnabled(true)
	moderateReceiveBufferOption := tcpip.TCPModerateReceiveBufferOption(true)
	for _, opt := range []tcpip.SettableTransportProtocolOption{
		&delayEnabled,
		&sackEnabled,
		&moderateReceiveBufferOption,
	} {
		if err := stk.SetTransportProtocolOption(tcp.ProtocolNumber, opt); err != nil {
			syslog.Fatalf("SetTransportProtocolOption(%d, %#v) failed: %s", tcp.ProtocolNumber, opt, err)
		}
	}

	req, np, err := device.NewNameProviderWithCtxInterfaceRequest()
	if err != nil {
		syslog.Fatalf("could not connect to device name provider service: %s", err)
	}
	appCtx.ConnectToEnvService(req)

	ns := &Netstack{
		dnsConfig:         dns.MakeServersConfig(stk.Clock()),
		nameProvider:      np,
		stack:             stk,
		nicRemovedHandler: &ndpDisp.dynamicAddressSourceObs,
	}

	ns.netstackService.mu.proxies = make(map[*netstack.NetstackEventProxy]struct{})
	ns.interfaceWatchers.mu.watchers = make(map[*interfaceWatcherImpl]struct{})
	ns.interfaceWatchers.mu.lastObserved = make(map[tcpip.NICID]interfaces.Properties)

	cobaltClient := NewCobaltClient()
	nudDisp.ns = ns
	ndpDisp.ns = ns
	ndpDisp.dhcpv6Obs.init(func() {
		cobaltClient.Register(&ndpDisp.dhcpv6Obs)
	})
	ndpDisp.dynamicAddressSourceObs.init(func() {
		cobaltClient.Register(&ndpDisp.dynamicAddressSourceObs)
	})
	ndpDisp.start(ctx)

	if err := ns.addLoopback(); err != nil {
		syslog.Fatalf("loopback: %s", err)
	}

	dnsWatchers := newDnsServerWatcherCollection(ns.dnsConfig.GetServersCacheAndChannel)

	socketProviderImpl := providerImpl{ns: ns}
	ns.stats = stats{
		Stats: stk.Stats(),
	}
	statsObserver := statsObserver{}
	statsObserver.init(func() {
		cobaltClient.Register(&statsObserver)
	})
	go statsObserver.run(context.Background(), socketStatsTimerPeriod, &ns.stats, ns.stack)
	appCtx.OutgoingService.AddDiagnostics("counters", &component.DirectoryWrapper{
		Directory: &inspectDirectory{
			asService: (&inspectImpl{
				inner: &statCounterInspectImpl{
					name:  "Networking Stat Counters",
					value: reflect.ValueOf(ns.stats),
				},
			}).asService,
		},
	})
	appCtx.OutgoingService.AddDiagnostics("interfaces", &component.DirectoryWrapper{
		Directory: &inspectDirectory{
			// asService is late-bound so that each call retrieves fresh NIC info.
			asService: func() *component.Service {
				return (&inspectImpl{
					inner: &nicInfoMapInspectImpl{value: ns.getIfStateInfo(stk.NICInfo())},
				}).asService()
			},
		},
	})

	appCtx.OutgoingService.AddDiagnostics("sockets", &component.DirectoryWrapper{
		Directory: &inspectDirectory{
			asService: (&inspectImpl{
				inner: &socketInfoMapInspectImpl{
					value: &ns.endpoints,
				},
			}).asService,
		},
	})

	// Minimal support for the inspect VMO format allows our profile protos to be
	// picked up by bug reports.
	//
	// To extract these serialized protos from inspect.json, jq can be used:
	//
	// cat iquery.json | \
	// jq '.[] | select(.path | contains("/pprof/")) | .contents.root.pprof.goroutine[4:]' | \
	// xargs echo | base64 --decode > goroutine
	func() {
		isolatedCache := filepath.Join("", "cache")
		if _, err := os.Stat(isolatedCache); err != nil {
			if os.IsNotExist(err) {
				// Emit a warning rather than an error to avoid tripping severity in
				// tests (netstack_debug intentionally exercises this path).
				_ = syslog.Warnf("isolated-cache-storage is not available; snapshots will not include pprof data: %s", err)
				return
			}
			_ = syslog.Fatalf("%s", err)
		}
		pprofCache := filepath.Join(isolatedCache, "pprof")
		if err := os.Mkdir(pprofCache, os.ModePerm); err != nil && !os.IsExist(err) {
			if err, ok := err.(*zx.Error); ok && err.Status == zx.ErrNoSpace {
				_ = syslog.Errorf("isolated-cache-storage is full; snapshots will not include pprof data: %s", err)
				return
			}
			_ = syslog.Fatalf("%s", err)
		}
		dir, run, err := pprof.Setup(pprofCache)
		if err != nil {
			_ = syslog.Fatalf("%s", err)
		}
		appCtx.OutgoingService.AddDiagnostics("pprof", dir)
		go func() {
			if err := run(); err != nil {
				_ = syslog.Errorf("pprof directory serving error; snapshots will not include pprof data: %s", err)
			}
		}()
	}()

	{
		stub := netstack.NetstackWithCtxStub{Impl: &netstackImpl{ns: ns}}
		appCtx.OutgoingService.AddService(
			netstack.NetstackName,
			func(ctx fidl.Context, c zx.Channel) error {
				pxy := netstack.NetstackEventProxy{Channel: c}
				// Send a synthetic InterfacesChanged event to each client when they join
				// Prevents clients from having to race GetInterfaces / InterfacesChanged.
				if err := pxy.OnInterfacesChanged(interfaces2ListToInterfacesList(ns.getNetInterfaces2())); err != nil {
					if err, ok := err.(*zx.Error); !ok || err.Status != zx.ErrPeerClosed {
						_ = syslog.Warnf("OnInterfacesChanged failed: %s", err)
					}
					return err
				}

				ns.netstackService.mu.Lock()
				ns.netstackService.mu.proxies[&pxy] = struct{}{}
				ns.netstackService.mu.Unlock()

				go func() {
					defer func() {
						ns.netstackService.mu.Lock()
						delete(ns.netstackService.mu.proxies, &pxy)
						ns.netstackService.mu.Unlock()
					}()
					component.ServeExclusive(ctx, &stub, c, func(err error) {
						_ = syslog.WarnTf(netstack.NetstackName, "%s", err)
					})
				}()

				return nil
			},
		)
	}

	{
		stub := stack.StackWithCtxStub{Impl: &stackImpl{
			ns:          ns,
			dnsWatchers: dnsWatchers,
		}}
		appCtx.OutgoingService.AddService(
			stack.StackName,
			func(ctx fidl.Context, c zx.Channel) error {
				go component.ServeExclusive(ctx, &stub, c, func(err error) {
					_ = syslog.WarnTf(stack.StackName, "%s", err)
				})
				return nil
			},
		)
	}

	{
		stub := stack.LogWithCtxStub{Impl: &logImpl{
			logger:     l,
			logPackets: &sniffer.LogPackets,
		}}
		appCtx.OutgoingService.AddService(
			stack.LogName,
			func(ctx fidl.Context, c zx.Channel) error {
				go component.ServeExclusive(ctx, &stub, c, func(err error) {
					_ = syslog.WarnTf(stack.LogName, "%s", err)
				})
				return nil
			})
	}

	{
		stub := socket.ProviderWithCtxStub{Impl: &socketProviderImpl}
		appCtx.OutgoingService.AddService(
			socket.ProviderName,
			func(ctx fidl.Context, c zx.Channel) error {
				go component.ServeExclusive(ctx, &stub, c, func(err error) {
					_ = syslog.WarnTf(socket.ProviderName, "%s", err)
				})
				return nil
			},
		)
	}

	{
		stub := routes.StateWithCtxStub{Impl: &routesImpl{ns.stack}}
		appCtx.OutgoingService.AddService(
			routes.StateName,
			func(ctx fidl.Context, c zx.Channel) error {
				go component.ServeExclusive(ctx, &stub, c, func(err error) {
					_ = syslog.WarnTf(routes.StateName, "%s", err)
				})
				return nil
			},
		)
	}

	{
		stub := interfaces.StateWithCtxStub{Impl: &interfaceStateImpl{ns: ns}}
		appCtx.OutgoingService.AddService(
			interfaces.StateName,
			func(ctx fidl.Context, c zx.Channel) error {
				go component.ServeExclusive(ctx, &stub, c, func(err error) {
					_ = syslog.WarnTf(interfaces.StateName, "%s", err)
				})
				return nil
			},
		)
	}

	{
		impl := &neighborImpl{stack: stk}

		viewStub := neighbor.ViewWithCtxStub{Impl: impl}
		appCtx.OutgoingService.AddService(
			neighbor.ViewName,
			func(ctx fidl.Context, c zx.Channel) error {
				go component.ServeExclusive(ctx, &viewStub, c, func(err error) {
					_ = syslog.WarnTf(neighbor.ViewName, "%s", err)
				})
				return nil
			},
		)

		controllerStub := neighbor.ControllerWithCtxStub{Impl: impl}
		appCtx.OutgoingService.AddService(
			neighbor.ControllerName,
			func(ctx fidl.Context, c zx.Channel) error {
				go component.ServeExclusive(ctx, &controllerStub, c, func(err error) {
					_ = syslog.WarnTf(neighbor.ControllerName, "%s", err)
				})
				return nil
			},
		)
	}

	if cobaltLogger, err := connectCobaltLogger(appCtx); err != nil {
		syslog.Warnf("could not initialize cobalt client: %s", err)
	} else {
		go func() {
			ticker := time.NewTicker(cobaltClientTimerPeriod)
			defer ticker.Stop()
			if err := cobaltClient.run(ctx, cobaltLogger, ticker.C); err != nil {
				syslog.Errorf("cobalt client exited unexpectedly: %s", err)
			}
		}()
	}

	ns.filter = filter.New(stk.PortManager)
	filter.AddOutgoingService(appCtx, ns.filter)

	appCtx.BindStartupHandle(context.Background())
}

// newSecretKey returns a new secret key.
func newSecretKey(keyLen int) ([]byte, error) {
	secretKey := make([]byte, keyLen)
	if _, err := io.ReadFull(rand.Reader, secretKey); err != nil {
		return nil, fmt.Errorf("failed to populate a new secret key of %d bytes: %s", keyLen, err)
	}
	return secretKey, nil
}

// newSecretKeyForOpaqueIID returns a new secret key for opaque IID generation.
func newSecretKeyForOpaqueIID() ([]byte, error) {
	return newSecretKey(header.OpaqueIIDSecretKeyMinBytes)
}

// getSecretKeyForOpaqueIID gets a secret key for opaque IID generation from the
// secure stash store service, or attempts to create one. If the stash service
// is unavailable, a temporary secret key will be returned.
func getSecretKeyForOpaqueIID(appCtx *component.Context) ([]byte, error) {
	syslog.VLogf(syslog.DebugVerbosity, "getting or creating secret key for opaque IID from secure stash store")

	// Connect to the secure stash store service.
	storeReq, store, err := stash.NewSecureStoreWithCtxInterfaceRequest()
	if err != nil {
		syslog.Errorf("could not create the request to connect to the %s service: %s", stash.SecureStoreName, err)
		return newSecretKeyForOpaqueIID()
	}
	defer store.Close()
	appCtx.ConnectToEnvService(storeReq)

	// Use our secure stash.
	if err := store.Identify(context.Background(), stashStoreIdentificationName); err != nil {
		syslog.Warnf("failed to identify as %s to the secure stash store: %s", stashStoreIdentificationName, err)
		return newSecretKeyForOpaqueIID()
	}
	storeAccessorReq, storeAccessor, err := stash.NewStoreAccessorWithCtxInterfaceRequest()
	if err != nil {
		syslog.Errorf("could not create the secure stash store accessor request: %s", err)
		return newSecretKeyForOpaqueIID()
	}
	defer storeAccessor.Close()
	if err := store.CreateAccessor(context.Background(), false /* readOnly */, storeAccessorReq); err != nil {
		syslog.Warnf("failed to create accessor to the secure stash store: %s", err)
		return newSecretKeyForOpaqueIID()
	}

	// Attempt to get the existing secret key.
	opaqueIIDSecretKeyValue, err := storeAccessor.GetValue(context.Background(), opaqueIIDSecretKeyName)
	if err != nil {
		syslog.Warnf("failed to get opaque IID secret key from secure stash store: %s", err)
		return newSecretKeyForOpaqueIID()
	}

	// If a key exists, make sure it is valid before returning it.
	//
	// The value should be stored as a base64 encoded string.
	//
	// We use a string because stash.Value.Bytesval uses a fuchsia.mem.Buffer
	// which uses a VMO (which uses memory in page size increments). This is
	// wasteful as the key only uses 16 bytes. We base64 encode the string
	// because stash.Value.Stringval expects an ascii string; the store returns an
	// error when flushing the store with a stash.Value.Stringval of raw bytes.
	if opaqueIIDSecretKeyValue != nil && opaqueIIDSecretKeyValue.Which() == stash.ValueStringval {
		syslog.VLogf(syslog.DebugVerbosity, "found a secret key for opaque IIDs in the secure stash store")

		if secretKey, err := base64.StdEncoding.DecodeString(opaqueIIDSecretKeyValue.Stringval); err != nil {
			syslog.Errorf("failed to decode the secret key string: %s", err)
		} else if l := len(secretKey); l != header.OpaqueIIDSecretKeyMinBytes {
			syslog.Errorf("invalid secret key for opaque IIDs; got length = %d, want = %d", l, header.OpaqueIIDSecretKeyMinBytes)
		} else {
			syslog.VLogf(syslog.DebugVerbosity, "using existing secret key for opaque IIDs")
			return secretKey, nil
		}
	}

	// Generate a new secret key as we either do not have one or the one we have
	// is invalid.
	syslog.VLogf(syslog.DebugVerbosity, "generating a new secret key for opaque IIDs")
	secretKey, err := newSecretKeyForOpaqueIID()
	if err != nil {
		return nil, err
	}

	// Store the newly generated key to the secure stash store as a base64
	// encoded string.
	if err := storeAccessor.SetValue(context.Background(), opaqueIIDSecretKeyName, stash.ValueWithStringval(base64.StdEncoding.EncodeToString(secretKey))); err != nil {
		syslog.Errorf("failed to set newly created secret key for opaque IID to secure stash store: %s", err)
		return secretKey, nil
	}
	flushResp, err := storeAccessor.Flush(context.Background())
	if err != nil {
		syslog.Errorf("failed to flush secure stash store with updated secret key for opaque IID: %s", err)
		return secretKey, nil
	}
	switch w := flushResp.Which(); w {
	case stash.StoreAccessorFlushResultErr:
		syslog.Errorf("got error response when flushing secure stash store with updated secret key for opaque IID: %s", flushResp.Err)
		return secretKey, nil

	case stash.StoreAccessorFlushResultResponse:
		syslog.VLogf(syslog.DebugVerbosity, "saved newly generated secret key for opaque IIDs to secure stash store")
		return secretKey, nil

	default:
		panic(fmt.Sprintf("unexpected store accessor flush result type: %d", w))
	}
}

func connectCobaltLogger(ctx *component.Context) (*cobalt.LoggerWithCtxInterface, error) {
	freq, cobaltLoggerFactory, err := cobalt.NewLoggerFactoryWithCtxInterfaceRequest()
	if err != nil {
		return nil, fmt.Errorf("could not connect to cobalt logger factory service: %s", err)
	}
	defer func() {
		_ = cobaltLoggerFactory.Close()
	}()
	ctx.ConnectToEnvService(freq)

	lreq, cobaltLogger, err := cobalt.NewLoggerWithCtxInterfaceRequest()
	if err != nil {
		return nil, fmt.Errorf("could not connect to cobalt logger service: %s", err)
	}
	result, err := cobaltLoggerFactory.CreateLoggerFromProjectId(context.Background(), networking_metrics.ProjectId, lreq)
	if err != nil {
		return nil, fmt.Errorf("CreateLoggerFromProjectId(%d, ...) = _, %s", networking_metrics.ProjectId, err)
	}
	if result != cobalt.StatusOk {
		_ = cobaltLogger.Close()
		return nil, fmt.Errorf("could not create logger for project %s: result: %s", networking_metrics.ProjectName, result)
	}

	return cobaltLogger, nil
}
