// Copyright 2021 Google LLC
//
// 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 monitor

import (
	"errors"
	"time"

	"policy-manager/pkg/configfetcher"
	"policy-manager/pkg/devicepolicy"
	"policy-manager/pkg/policyenforcer"
	"policy-manager/pkg/sysapi"
	"policy-manager/pkg/systemd"
	"policy-manager/protos"

	"github.com/golang/glog"

	"github.com/golang/protobuf/proto"
)

const (
	// instanceConfigFile is the file that stores the config related to
	// policy manager.
	instanceConfigFile = "/var/lib/devicesettings/instance_config"

	// devicePolicyFile is the default file of the device policy. This file is
	// used by crash-sender service and update-engine serivice to get any
	// config related to them.
	devicePolicyFile = "/var/lib/devicesettings/policy"

	// publicKeyFile is the file containing the public key that will be used
	// to verify the signature on the device policy file.
	// The key will be encoded using DER-encoded PKIX format.
	// Note that the file name is decided by Chrome OS.
	publicKeyFile = "/var/lib/devicesettings/owner.key"

	// privateKeyFile is the file containing the private key that will be
	// used to sign the policy file.
	// The key will be encoded using ASN.1 DER encoded form.
	// Note that we are signing the policy file locally since we do not want
	// to do any key management on the server side.
	privateKeyFile = "/var/lib/devicesettings/private.key"

	// GCEMetadataURL is the URL of metadata server where we can query
	// metadata tags and their values.
	gceMetadataURL = "http://metadata.google.internal/computeMetadata/v1"

	systemctlCmd = "systemctl"
)

var serviceMonitor = map[string]string{
	"loggingService":    "stackdriver-logging.service",
	"monitoringService": "node-problem-detector.service",
	"metricsService":    "crash-reporter.service",
	"updateService":     "update-engine.service",
}

// resolveEnforcementConfig sets enforcement related fields in userConfig to
// true if either logging or monitoring feature is enabled, or if the device
// policy file has the corresponding enforcement option set to true.
// If failed to find/parse the device policy file, simply assumes the enforcement
// options are set to false on disk.
func resolveEnforcementConfig(userConfig *protos.InstanceConfig) error {
	if userConfig == nil {
		return errors.New("value of userConfig is nil")
	}

	// Set HealthMonitorConfig.Enforced to false as default value.
	if userConfig.HealthMonitorConfig == nil {
		userConfig.HealthMonitorConfig = new(protos.HealthMonitorConfig)
	}
	userConfig.HealthMonitorConfig.Enforced = proto.Bool(false)

	// Set HealthMonitorConfig.Enforced to true if either logging or monitoring is enabled and return.
	if userConfig.HealthMonitorConfig.GetLoggingEnabled() || userConfig.HealthMonitorConfig.GetMonitoringEnabled() {
		userConfig.HealthMonitorConfig.Enforced = proto.Bool(true)
		return nil
	}

	// Read the existing state on disk.
	onDiskConfig, err := devicepolicy.GetInstanceConfig(instanceConfigFile)
	if err != nil {
		return err
	}

	// userConfig should respect onDiskConfig when both logging and monitoring are disabled.
	if onDiskConfig != nil && onDiskConfig.HealthMonitorConfig != nil {
		userConfig.HealthMonitorConfig.Enforced = proto.Bool(onDiskConfig.HealthMonitorConfig.GetEnforced())
	}
	return nil
}

// updateInstanceConfig queries the API (if needed) for new instance config and
// changes the device policy stored in the policy file. userConfig is what we
// got from GCE metadata (it can even be nil). The API query to backend is not
// made if the given userConfig can be locally understood by Policy Manager.
// Note that the given devicepolicy.Manager should be initialized.
func updateInstanceConfig(userConfig *protos.InstanceConfig) error {
	if err := resolveEnforcementConfig(userConfig); err != nil {
		return err
	}
	return devicepolicy.SetInstanceConfig(userConfig, devicePolicyFile, instanceConfigFile, publicKeyFile, privateKeyFile)
}

// initDevicePolicyOrDie initializes the device policy. It's success ensures that the default
// devicepolicy file and all required keys to access it are present and consistent. If
// something fails, this function logs the error message and exists the process.
func initDevicePolicyOrDie() error {
	initConfig := &protos.InstanceConfig{
		MetricsEnabled: proto.Bool(false),
		UpdateStrategy: proto.String(""),
		HealthMonitorConfig: &protos.HealthMonitorConfig{
			Enforced:          proto.Bool(false),
			LoggingEnabled:    proto.Bool(false),
			MonitoringEnabled: proto.Bool(false),
		},
	}

	if err := resolveEnforcementConfig(initConfig); err != nil {
		return err
	}

	// Stopping the crash-reporter service. When GCE instance boots, crash-reporter service
	// is in `Activating` state due to which it is returning error and we don't
	// need this service until cos-metrics-enabled is set to true.
	systemdClient := systemd.NewSystemdClient(systemctlCmd)
	if err := systemdClient.StopUnit(serviceMonitor["metricsService"]); err != nil {
		return err
	}

	return devicepolicy.InitDevicePolicy(initConfig, devicePolicyFile, instanceConfigFile, publicKeyFile, privateKeyFile)
}

// InitDevicePolicy is the handler function for initializing the device policy.
func InitDevicePolicy() {
	glog.Info("Starting device policy initialization...")

	if err := initDevicePolicyOrDie(); err != nil {
		glog.Exitf("Error initializing device policy: %v", err)
	}

	glog.Info("Device policy initialized successfully!")
}

// HandleMonitorCmd is the handler function for running Policy Manager
// in monitor mode, which watches the metadata for new update configuration
// and periodically sends the status updates.
func HandleMonitorCmd() {
	glog.Info("Started in monitor mode")

	// Send notify command to notify systemd if initialization was successful
	if _, _, err := sysapi.RunCommand("systemd-notify", "--ready", "--status='Initialization was successful'"); err != nil {
		glog.Errorf("error in notifying systemd: %s\n", err)
	}

	// Get instance ID.
	var instanceID uint64
	for {
		id, err := configfetcher.GetInstanceID()
		if err == nil {
			instanceID = id
			break
		}
		glog.Errorf("error while fetching instance id: %v", err)
		time.Sleep(1 * time.Minute)
	}
	glog.Infof("Detected instance ID is: %d", instanceID)

	initDevicePolicyOrDie()
	systemdClient := systemd.NewSystemdClient(systemctlCmd)
	policyEnforcer := policyenforcer.NewPolicyEnforcer(*systemdClient)

	userConfig := make(chan *protos.InstanceConfig)
	go configfetcher.PollUserConfig(userConfig, gceMetadataURL)

	for {
		instanceConfig := <-userConfig
		// userConfigUpdate returns the latest value of user config when the metadata are updated.
		glog.Infof("Using InstanceConfig: %v", instanceConfig)

		if err := updateInstanceConfig(instanceConfig); err != nil {
			glog.Warning(err)
		}
		if err := policyEnforcer.UpdateServiceState(instanceConfigFile, serviceMonitor); err != nil {
			glog.Errorf("error while updating instance: %v", err)
		}
	}
}
