// Copyright 2020 The Monogon Project Authors.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed 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 event

import (
	"context"
	"fmt"
	"net"
	"time"
)

// NetworkStatus is example data that will be stored in a Value.
type NetworkStatus struct {
	ExternalAddress net.IP
	DefaultGateway net.IP
}

// NetworkStatusWatcher is a typesafe wrapper around a Watcher.
type NetworkStatusWatcher struct {
	watcher Watcher
}

// Get wraps Watcher.Get and performs type assertion.
func (s *NetworkStatusWatcher) Get(ctx context.Context) (*NetworkStatus, error) {
	val, err := s.watcher.Get(ctx)
	if err != nil {
		return nil, err
	}
	ns := val.(NetworkStatus)
	return &ns, nil
}

// NetworkService is a fake/example network service that is responsible for
// communicating the newest information about a machine's network configuration
// to consumers/watchers.
type NetworkService struct {
	Provider MemoryValue
}

// Watch is a thin wrapper around Value.Watch that returns the typesafe
// NetworkStatusWatcher wrapper.
func (s *NetworkService) Watch() NetworkStatusWatcher {
	watcher := s.Provider.Watch()
	return NetworkStatusWatcher{
		watcher: watcher,
	}
}

// Run pretends to execute the network service's main logic loop, in which it
// pretends to have received an IP address over DHCP, and communicates that to
// consumers/watchers.
func (s *NetworkService) Run(ctx context.Context) {
	s.Provider.Set(NetworkStatus{
		ExternalAddress: nil,
		DefaultGateway: nil,
	})

	select {
	case <-time.After(100*time.Millisecond):
	case <-ctx.Done():
			return
	}

	fmt.Printf("NS: Got DHCP Lease\n")
	s.Provider.Set(NetworkStatus{
		ExternalAddress: net.ParseIP("203.0.113.24"),
		DefaultGateway: net.ParseIP("203.0.113.1"),
	})

	select {
	case <-time.After(100*time.Millisecond):
	case <-ctx.Done():
		return
	}

	fmt.Printf("NS: DHCP Address changed\n")
	s.Provider.Set(NetworkStatus{
		ExternalAddress: net.ParseIP("203.0.113.103"),
		DefaultGateway: net.ParseIP("203.0.113.1"),
	})

	time.Sleep(100 * time.Millisecond)
}

// ExampleValue_full demonstrates a typical usecase for Event Values, in which
// a mock network service lets watchers know that the machine on which the code
// is running has received a new network configuration.
// It also shows the typical boilerplate required in order to wrap a Value (eg.
// MemoryValue) within a typesafe wrapper.
func ExampleValue_full() {
	ctx, ctxC := context.WithCancel(context.Background())
	defer ctxC()

	// Create a fake NetworkService.
	ns := NetworkService{}

	// Run an /etc/hosts updater. It will watch for updates from the NetworkService
	// about the current IP address of the node.
	go func() {
		w := ns.Watch()
		for {
			status, err := w.Get(ctx)
			if err != nil {
				break
			}
			if status.ExternalAddress == nil {
				continue
			}
			// Pretend to write /etc/hosts with the newest ExternalAddress.
			// In production code, you would also check for whether ExternalAddress has
			// changed from the last written value, if writing to /etc/hosts is expensive.
			fmt.Printf("/etc/hosts: foo.example.com is now %s\n", status.ExternalAddress.String())
		}
	}()

	// Run fake network service.
	ns.Run(ctx)

	// Output:
	// NS: Got DHCP Lease
	// /etc/hosts: foo.example.com is now 203.0.113.24
	// NS: DHCP Address changed
	// /etc/hosts: foo.example.com is now 203.0.113.103
}

