/*
 * Copyright 2018-present Open Networking Foundation

 * 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 dmiserver

import (
	"context"

	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"

	dmi "github.com/opencord/device-management-interface/go/dmi"
)

//ListMetrics lists the supported metrics for the passed device.
func (dms *DmiAPIServer) ListMetrics(ctx context.Context, req *dmi.HardwareID) (*dmi.ListMetricsResponse, error) {
	logger.Debugf("ListMetrics invoked with request %+v", req)
	metrics := getMetricsList()

	return &dmi.ListMetricsResponse{
		Status: dmi.Status_OK_STATUS,
		Reason: 0,
		Metrics: &dmi.MetricsConfig{
			Metrics: metrics,
		},
	}, nil
}

//UpdateMetricsConfiguration updates the configuration of the list of metrics in the request
func (dms *DmiAPIServer) UpdateMetricsConfiguration(ctx context.Context, req *dmi.MetricsConfigurationRequest) (*dmi.MetricsConfigurationResponse, error) {
	logger.Debugf("UpdateMetricConfiguration invoked with request %+v", req)

	if req == nil || req.Operation == nil {
		return &dmi.MetricsConfigurationResponse{
			Status: dmi.Status_ERROR_STATUS,
			//TODO reason must be INVALID_PARAMS, currently this is available in Device Management interface (DMI),
			// change below reason with type INVALID_PARAMS once DMI is updated
			Reason: dmi.Reason_UNDEFINED_REASON,
		}, status.Errorf(codes.FailedPrecondition, "request is nil")
	}

	switch x := req.Operation.(type) {
	case *dmi.MetricsConfigurationRequest_Changes:
		for _, chMetric := range x.Changes.Metrics {
			UpdateMetricConfig(chMetric)
		}
	case *dmi.MetricsConfigurationRequest_ResetToDefault:
		logger.Debugf("To be implemented later")
	case nil:
		// The field is not set.
		logger.Debugf("Update request operation type is nil")
		return &dmi.MetricsConfigurationResponse{
			Status: dmi.Status_UNDEFINED_STATUS,
		}, nil
	}

	return &dmi.MetricsConfigurationResponse{
		Status: dmi.Status_OK_STATUS,
	}, nil
}

//GetMetric gets the instantenous value of a metric
func (dms *DmiAPIServer) GetMetric(ctx context.Context, req *dmi.GetMetricRequest) (*dmi.GetMetricResponse, error) {
	logger.Debugf("GetMetric invoked with request %+v", req)

	if req == nil || req.GetMetricId() < 0 {
		return &dmi.GetMetricResponse{
			Status: dmi.Status_ERROR_STATUS,
			//TODO reason must be INVALID_PARAMS, currently this is available in Device Management interface (DMI),
			// change below reason with type INVALID_PARAMS once DMI is updated
			Reason: dmi.Reason_UNDEFINED_REASON,
			Metric: &dmi.Metric{},
		}, status.Errorf(codes.FailedPrecondition, "request is nil")
	}

	if dms.root == nil {
		return &dmi.GetMetricResponse{
			Status: dmi.Status_ERROR_STATUS,
			Reason: dmi.Reason_INTERNAL_ERROR,
			Metric: &dmi.Metric{},
		}, status.Errorf(codes.FailedPrecondition, "Device is not managed, please start managing device to get the metric")
	}
	comp := findComponent(dms.root.Children, req.MetaData.ComponentUuid.Uuid)
	metric := getMetric(comp, req.GetMetricId())
	return &dmi.GetMetricResponse{
		Status: dmi.Status_OK_STATUS,
		Reason: dmi.Reason_UNDEFINED_REASON,
		Metric: metric,
	}, nil
}
