// 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 dbus

import (
	"fmt"
	"policy_manager/policymanagerproto"
	"strings"

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

// Implementation of the UpdateEngineClient interface that interacts with update-engine.

const (
	updateEngineObjectName  = "org.chromium.UpdateEngine"
	updateEngineObjectPath  = "/org/chromium/UpdateEngine"
	setChannelMethod        = "org.chromium.UpdateEngineInterface.SetChannel"
	attemptUpdateMethod     = "org.chromium.UpdateEngineInterface.AttemptUpdate"
	getStatusAdvancedMethod = "org.chromium.UpdateEngineInterface.GetStatusAdvanced"
	statusUpdateSignal      = "org.chromium.UpdateEngineInterface.StatusUpdate"
	dBusAddMatchMethod      = "org.freedesktop.DBus.AddMatch"
)

type updateEngineClientImpl struct {
	// A shared connection to the system bus.
	conn Conn
}

// NewUpdateEngineClient() creates a new UpdateEngineClient.
// This method is Goroutine-safe.
func NewUpdateEngineClient() (UpdateEngineClient, error) {
	conn, err := SystemBus()
	if err != nil {
		return nil, err
	}
	return &updateEngineClientImpl{conn}, nil
}

// SetChannel Sets the target channel for update.
func (client *updateEngineClientImpl) SetChannel(targetChannel string) error {
	call := client.conn.Object(
		updateEngineObjectName, updateEngineObjectPath).Call(
		setChannelMethod,
		0, /* godbus flag */
		targetChannel,
		false /* isPowerWashAllowed */)
	return call.GetError()
}

// AttemptUpdate sends a request to update-engine to check for update.
func (client *updateEngineClientImpl) AttemptUpdate() error {
	call := client.conn.Object(
		updateEngineObjectName, updateEngineObjectPath).Call(
		attemptUpdateMethod,
		0,  /* godbus flag */
		"", /* appVersion  */
		"" /* omahaUrl */)
	return call.GetError()
}

// GetStatus returns the update status
func (client *updateEngineClientImpl) GetStatus() (
	*policymanagerproto.StatusResult, error) {
	var updateStatusBytes []byte
	updateStatus := new(policymanagerproto.StatusResult)
	if err := client.conn.Object(updateEngineObjectName, updateEngineObjectPath).Call(
		getStatusAdvancedMethod, 0).Store(&updateStatusBytes); err != nil {
		return nil, fmt.Errorf("failed to fetch update status: %s", err)
	}
	if err := proto.Unmarshal(updateStatusBytes, updateStatus); err != nil {
		return nil, fmt.Errorf("failed to unmarshal UpdateStatus %s: %s",
			updateStatusBytes, updateStatus)
	}
	return updateStatus, nil
}

// SubscribeStatusUpdate subscribes the status update of update-engine.
// It returns a channel so that any udpate status change of udpate-engine
// will be sent to the channel.
func (client *updateEngineClientImpl) SubscribeStatusUpdate() (
	<-chan UEGetStatusResponse, error) {
	idx := strings.LastIndex(statusUpdateSignal, ".")
	addMatchArgs := fmt.Sprintf(
		"type='signal',path='%s',interface='%s',member='%s'",
		updateEngineObjectPath,
		statusUpdateSignal[:idx],
		statusUpdateSignal[idx+1:])
	err := client.conn.BusObject().Call(
		dBusAddMatchMethod, 0, addMatchArgs).GetError()
	if err != nil {
		return nil, err
	}
	ch := make(chan *godbus.Signal, 10)
	client.conn.Signal(ch)

	out := make(chan UEGetStatusResponse, 10)
	go func() {
		for signal := range ch {
			out <- UEGetStatusResponse{
				LastCheckedTime: signal.Body[0].(int64),
				Progress:        signal.Body[1].(float64),
				UpdateStatus:    signal.Body[2].(string),
				NewVersion:      signal.Body[3].(string),
				NewSize:         signal.Body[4].(int64),
			}
		}
	}()
	return out, nil
}
