/*
 * 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.MetricsConfigurationResponse_INVALID_METRIC,
		}, 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 not available in Device Management interface (DMI),
			// change below reason with type INVALID_PARAMS once DMI is updated
			Reason: dmi.GetMetricResponse_INVALID_METRIC,
			Metric: &dmi.Metric{},
		}, status.Errorf(codes.FailedPrecondition, "request is nil")
	}

	if dms.root == nil {
		return &dmi.GetMetricResponse{
			Status: dmi.Status_ERROR_STATUS,
			Reason: dmi.GetMetricResponse_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.GetMetricResponse_UNDEFINED_REASON,
		Metric: metric,
	}, nil
}
