/*
 * Copyright 2017 Banco Bilbao Vizcaya Argentaria, S.A.
 *
 * 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 com.bbva.arq.devops.ae.mirrorgate.service;

import com.bbva.arq.devops.ae.mirrorgate.core.dto.DashboardDTO;
import com.bbva.arq.devops.ae.mirrorgate.core.dto.UserMetricDTO;
import com.bbva.arq.devops.ae.mirrorgate.dto.HistoricUserMetricDTO;
import com.bbva.arq.devops.ae.mirrorgate.mapper.UserMetricMapper;
import com.bbva.arq.devops.ae.mirrorgate.model.UserMetric;
import com.bbva.arq.devops.ae.mirrorgate.repository.UserMetricsRepository;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class UserMetricsServiceImpl implements UserMetricsService {

    private final DashboardService dashboardService;
    private final UserMetricsRepository userMetricsRepository;
    private final HistoricUserMetricService historicUserMetricService;

    @Autowired
    public UserMetricsServiceImpl(DashboardService dashboardService, UserMetricsRepository userMetricsRepository
                                , HistoricUserMetricService historicUserMetricService){
        this.dashboardService = dashboardService;
        this.userMetricsRepository = userMetricsRepository;
        this.historicUserMetricService = historicUserMetricService;
    }

    @Override
    public List<String> getAnalyticViewIds() {
        return dashboardService.getActiveDashboards().stream()
                .flatMap((d) -> d.getAnalyticViews() == null ?
                        Stream.empty() :
                        d.getAnalyticViews().stream()
                )
                .distinct()
                .collect(Collectors.toList());
    }

    @Override
    public List<UserMetricDTO> getMetricsByCollectorId(String collectorId) {
        return userMetricsRepository.findAllByCollectorId(collectorId).stream()
                .map(UserMetricMapper::map).collect(Collectors.toList());
    }

    @Override
    public List<UserMetricDTO> saveMetrics(Iterable<UserMetricDTO> metrics) {
        List<UserMetric> toSave = StreamSupport.stream(metrics.spliterator(), false)
                .map(UserMetricMapper::map)
                .collect(Collectors.toList());

        Iterable<UserMetric> saved = userMetricsRepository.save(toSave);

        //send to historic
        historicUserMetricService.addToCurrentPeriod(saved);

        return toSave.stream().map(UserMetricMapper::map).collect(Collectors.toList());
    }

    @Override
    public List<UserMetricDTO> getMetricsForDashboard(DashboardDTO dashboard) {
        List<String> views = dashboard.getAnalyticViews();
        if (views == null || views.isEmpty()) {
            return new ArrayList<>();
        }

        return userMetricsRepository.findAllByViewIdInWithNon0Values(views)
                    .stream()
                    .map(UserMetricMapper::map)
                    .map(u ->  {
                        List<HistoricUserMetricDTO> historicUserMetrics =
                            historicUserMetricService.getHistoricMetricsForDashboard(dashboard,u.getName(),24);

                        if(!historicUserMetrics.isEmpty()){
                            u.setLongTermTendency(getLongTermTendency(historicUserMetrics));
                            u.setShortTermTendency(getShortTermTendency(historicUserMetrics, 3l));
                        }

                        return u;
                    }).collect(Collectors.toList());
    }

    private double getLongTermTendency(List<HistoricUserMetricDTO> historicUserMetrics){
        return historicUserMetrics.stream()
                    .mapToDouble(HistoricUserMetricDTO::getValue)
                    .sum()/historicUserMetrics.size();
    }

    private double getShortTermTendency(List<HistoricUserMetricDTO> historicUserMetrics, long limit){
        return historicUserMetrics.stream()
                    .limit(limit)
                    .mapToDouble(HistoricUserMetricDTO::getValue)
                    .sum()/limit;
    }

}

@@ -3902,32 +3902,28 @@
 ency(get
-LongTermTendency
+AverageValue
 (histori
@@ -3992,33 +3992,28 @@
 ency(get
-ShortTermTendency
+AverageValue
 (histori
@@ -4028,12 +4028,22 @@
 rics
+.subList(0
 , 3
-l
+)
 ));%0A
@@ -4185,32 +4185,28 @@
 uble get
-LongTermTendency
+AverageValue
 (List%3CHi
@@ -4350,32 +4350,32 @@
 cDTO::getValue)%0A
+
                 
@@ -4424,293 +4424,6 @@
  %7D%0A%0A
-    private double getShortTermTendency(List%3CHistoricUserMetricDTO%3E historicUserMetrics, long limit)%7B%0A        return historicUserMetrics.stream()%0A                    .limit(limit)%0A                    .mapToDouble(HistoricUserMetricDTO::getValue)%0A                    .sum()/limit;%0A    %7D%0A%0A
 %7D%0A

refactor tendencies method