package metrics

import (
	"Toolbox/goDataverseStrict/connect"
	"encoding/json"
	"log"
	"sort"
	"strconv"
	"strings"
	"time"

	"golang.org/x/exp/slices"
)

type (
	MetricsType          string // To ensure, that the set of constants is limited (a kind of enumeration)
	MetricsDataCountType string
	ReturnformatType     string
	SearchType           string
)

const PDPURL = "https://pdp.archium.org"

// const IDRequestCriteriaPrefix = "input_"
const (
	IDRequestCriteriaPrefix    = "get_input_"
	IDRequestTextPrefix        = "text_input_"
	IDRequestHideDisplayPrefix = "span_input_"
	IDFormSubmit               = "input_form_submit"
)

const StaticMetricsAPIbody = "/api/info/metrics/"

const (
	//Level0
	MT0unset               MetricsType = "" //TODO: Platzhalter für unbelegt, eventuell unnötig
	MT1dataverses          MetricsType = "dataverses"
	MT2datasets            MetricsType = "datasets"
	MT3files               MetricsType = "files"
	MT4downloads           MetricsType = "downloads"
	MT5filedownloads       MetricsType = "filedownloads"
	MT6uniquefiledownloads MetricsType = "uniquefiledownloads"
	MT7makeDataCount       MetricsType = "makeDataCount"

	//Level1
	MDCT0unset                   MetricsDataCountType = "" //TODO: Platzhalter für unbelegt, eventuell unnötig
	MDCT1viewsTotal              MetricsDataCountType = "viewsTotal"
	MDCT2viewsTotalRegular       MetricsDataCountType = "viewsTotalRegular"
	MDCT3viewsTotalMachine       MetricsDataCountType = "viewsTotalMachine"
	MDCT4viewsUnique             MetricsDataCountType = "viewsUnique"
	MDCT5viewsUniqueRegular      MetricsDataCountType = "viewsUniqueRegular"
	MDCT6viewsUniqueMachine      MetricsDataCountType = "viewsUniqueMachine"
	MDCT7downloadsTotal          MetricsDataCountType = "downloadsTotal"
	MDCT8downloadsTotalRegular   MetricsDataCountType = "downloadsTotalRegular"
	MDCT9downloadsTotalMachine   MetricsDataCountType = "downloadsTotalMachine"
	MDCT10downloadsUnique        MetricsDataCountType = "downloadsUnique"
	MDCT11downloadsUniqueRegular MetricsDataCountType = "downloadsUniqueRegular"
	MDCT12downloadsUniqueMachine MetricsDataCountType = "downloadsUniqueMachine"
	MDCT13citations              MetricsDataCountType = "citations"

	//Level2
	ST0unset    SearchType = ""      //TODO: Platzhalter für unbelegt, eventuell unnötig
	ST1total    SearchType = "total" // ISt eigentlich ein Platzhalter. "total" gibt es nicht und wirkt dann, wenn der SearchType weggelassen wird.
	ST2tomonth  SearchType = "toMonth"
	ST3pastdays SearchType = "pastDays"
	ST4monthly  SearchType = "monthly"
	ST5tree     SearchType = "tree"

	//Level3
	RT0unset ReturnformatType = "" //TODO: Platzhalter für unbelegt, eventuell unnötig
	RT1json  ReturnformatType = "application/json"
	RT2csv   ReturnformatType = "text/csv"
)

type InputLevel3 = map[ReturnformatType]bool

var OneJumpPointResultformat = map[ReturnformatType]bool{
	RT0unset: false,
	RT1json:  false,
	RT2csv:   false,
}

type InputLevel2 = map[SearchType]InputLevel3

var OneJumpPointSearchType = InputLevel2{
	ST0unset:    OneJumpPointResultformat,
	ST1total:    OneJumpPointResultformat,
	ST2tomonth:  OneJumpPointResultformat,
	ST3pastdays: OneJumpPointResultformat,
	ST4monthly:  OneJumpPointResultformat,
	ST5tree:     OneJumpPointResultformat,
}

type InputLevel1 = map[MetricsDataCountType]InputLevel2

var OneJumpPointMetricsDataCountType = InputLevel1{
	MDCT0unset:                   OneJumpPointSearchType,
	MDCT1viewsTotal:              OneJumpPointSearchType,
	MDCT2viewsTotalRegular:       OneJumpPointSearchType,
	MDCT3viewsTotalMachine:       OneJumpPointSearchType,
	MDCT4viewsUnique:             OneJumpPointSearchType,
	MDCT5viewsUniqueRegular:      OneJumpPointSearchType,
	MDCT6viewsUniqueMachine:      OneJumpPointSearchType,
	MDCT7downloadsTotal:          OneJumpPointSearchType,
	MDCT8downloadsTotalRegular:   OneJumpPointSearchType,
	MDCT9downloadsTotalMachine:   OneJumpPointSearchType,
	MDCT10downloadsUnique:        OneJumpPointSearchType,
	MDCT11downloadsUniqueRegular: OneJumpPointSearchType,
	MDCT12downloadsUniqueMachine: OneJumpPointSearchType,
	MDCT13citations:              OneJumpPointSearchType,
}

type InputLevel0 = map[MetricsType]InputLevel1

var OldOneJumpPointSet = InputLevel0{
	MT0unset:               OneJumpPointMetricsDataCountType,
	MT1dataverses:          OneJumpPointMetricsDataCountType,
	MT2datasets:            OneJumpPointMetricsDataCountType,
	MT3files:               OneJumpPointMetricsDataCountType,
	MT4downloads:           OneJumpPointMetricsDataCountType,
	MT5filedownloads:       OneJumpPointMetricsDataCountType,
	MT6uniquefiledownloads: OneJumpPointMetricsDataCountType,
	MT7makeDataCount:       OneJumpPointMetricsDataCountType,
}

type OneJumpPointSet struct {
	Level0 MetricsType
	Level1 MetricsDataCountType
	Level2 SearchType
	Level3 ReturnformatType
	Active bool
}

var OneJumpPoints []OneJumpPointSet

// Presets
func init() {
	//OneJumpPoints = make([]OneJumpPointSet, 910, 910)

	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT1dataverses, Level1: MDCT0unset, Level2: ST1total, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT1dataverses, Level1: MDCT0unset, Level2: ST2tomonth, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT1dataverses, Level1: MDCT0unset, Level2: ST3pastdays, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT1dataverses, Level1: MDCT0unset, Level2: ST4monthly, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT1dataverses, Level1: MDCT0unset, Level2: ST5tree, Level3: RT1json, Active: true})

	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT2datasets, Level1: MDCT0unset, Level2: ST1total, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT2datasets, Level1: MDCT0unset, Level2: ST2tomonth, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT2datasets, Level1: MDCT0unset, Level2: ST3pastdays, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT2datasets, Level1: MDCT0unset, Level2: ST4monthly, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT2datasets, Level1: MDCT0unset, Level2: ST5tree, Level3: RT1json, Active: true})

	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT3files, Level1: MDCT0unset, Level2: ST1total, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT3files, Level1: MDCT0unset, Level2: ST2tomonth, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT3files, Level1: MDCT0unset, Level2: ST3pastdays, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT3files, Level1: MDCT0unset, Level2: ST4monthly, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT3files, Level1: MDCT0unset, Level2: ST5tree, Level3: RT1json, Active: true})

	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT4downloads, Level1: MDCT0unset, Level2: ST1total, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT4downloads, Level1: MDCT0unset, Level2: ST2tomonth, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT4downloads, Level1: MDCT0unset, Level2: ST3pastdays, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT4downloads, Level1: MDCT0unset, Level2: ST4monthly, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT4downloads, Level1: MDCT0unset, Level2: ST5tree, Level3: RT1json, Active: true})

	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT5filedownloads, Level1: MDCT0unset, Level2: ST1total, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT5filedownloads, Level1: MDCT0unset, Level2: ST2tomonth, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT5filedownloads, Level1: MDCT0unset, Level2: ST3pastdays, Level3: RT1json, Active: false}) // Nicht valide
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT5filedownloads, Level1: MDCT0unset, Level2: ST4monthly, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT5filedownloads, Level1: MDCT0unset, Level2: ST5tree, Level3: RT1json, Active: true})

	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT6uniquefiledownloads, Level1: MDCT0unset, Level2: ST1total, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT6uniquefiledownloads, Level1: MDCT0unset, Level2: ST2tomonth, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT6uniquefiledownloads, Level1: MDCT0unset, Level2: ST3pastdays, Level3: RT1json, Active: false}) // Nicht valide
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT6uniquefiledownloads, Level1: MDCT0unset, Level2: ST4monthly, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT6uniquefiledownloads, Level1: MDCT0unset, Level2: ST5tree, Level3: RT1json, Active: true})

	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT1viewsTotal, Level2: ST0unset, Level3: RT1json, Active: true})

	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT1viewsTotal, Level2: ST1total, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT1viewsTotal, Level2: ST2tomonth, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT1viewsTotal, Level2: ST3pastdays, Level3: RT1json, Active: false}) // Nicht valide
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT1viewsTotal, Level2: ST4monthly, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT1viewsTotal, Level2: ST5tree, Level3: RT1json, Active: true})

	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT2viewsTotalRegular, Level2: ST1total, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT2viewsTotalRegular, Level2: ST2tomonth, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT2viewsTotalRegular, Level2: ST3pastdays, Level3: RT1json, Active: false}) // Nicht valide
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT2viewsTotalRegular, Level2: ST4monthly, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT2viewsTotalRegular, Level2: ST5tree, Level3: RT1json, Active: true})

	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT3viewsTotalMachine, Level2: ST1total, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT3viewsTotalMachine, Level2: ST2tomonth, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT3viewsTotalMachine, Level2: ST3pastdays, Level3: RT1json, Active: false}) // Nicht valide
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT3viewsTotalMachine, Level2: ST4monthly, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT3viewsTotalMachine, Level2: ST5tree, Level3: RT1json, Active: true})

	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT4viewsUnique, Level2: ST1total, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT4viewsUnique, Level2: ST2tomonth, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT4viewsUnique, Level2: ST3pastdays, Level3: RT1json, Active: false}) // Nicht valide
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT4viewsUnique, Level2: ST4monthly, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT4viewsUnique, Level2: ST5tree, Level3: RT1json, Active: true})

	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT5viewsUniqueRegular, Level2: ST1total, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT5viewsUniqueRegular, Level2: ST2tomonth, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT5viewsUniqueRegular, Level2: ST3pastdays, Level3: RT1json, Active: false}) // Nicht valide
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT5viewsUniqueRegular, Level2: ST4monthly, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT5viewsUniqueRegular, Level2: ST5tree, Level3: RT1json, Active: true})

	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT6viewsUniqueMachine, Level2: ST1total, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT6viewsUniqueMachine, Level2: ST2tomonth, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT6viewsUniqueMachine, Level2: ST3pastdays, Level3: RT1json, Active: false}) // Nicht valide
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT6viewsUniqueMachine, Level2: ST4monthly, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT6viewsUniqueMachine, Level2: ST5tree, Level3: RT1json, Active: true})

	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT7downloadsTotal, Level2: ST1total, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT7downloadsTotal, Level2: ST2tomonth, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT7downloadsTotal, Level2: ST3pastdays, Level3: RT1json, Active: false}) // Nicht valide
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT7downloadsTotal, Level2: ST4monthly, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT7downloadsTotal, Level2: ST5tree, Level3: RT1json, Active: true})

	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT8downloadsTotalRegular, Level2: ST1total, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT8downloadsTotalRegular, Level2: ST2tomonth, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT8downloadsTotalRegular, Level2: ST3pastdays, Level3: RT1json, Active: false}) // Nicht valide
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT8downloadsTotalRegular, Level2: ST4monthly, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT8downloadsTotalRegular, Level2: ST5tree, Level3: RT1json, Active: true})

	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT9downloadsTotalMachine, Level2: ST1total, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT9downloadsTotalMachine, Level2: ST2tomonth, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT9downloadsTotalMachine, Level2: ST3pastdays, Level3: RT1json, Active: false}) // Nicht valide
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT9downloadsTotalMachine, Level2: ST4monthly, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT9downloadsTotalMachine, Level2: ST5tree, Level3: RT1json, Active: true})

	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT10downloadsUnique, Level2: ST1total, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT10downloadsUnique, Level2: ST2tomonth, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT10downloadsUnique, Level2: ST3pastdays, Level3: RT1json, Active: false}) // Nicht valide
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT10downloadsUnique, Level2: ST4monthly, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT10downloadsUnique, Level2: ST5tree, Level3: RT1json, Active: true})

	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT11downloadsUniqueRegular, Level2: ST1total, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT11downloadsUniqueRegular, Level2: ST2tomonth, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT11downloadsUniqueRegular, Level2: ST3pastdays, Level3: RT1json, Active: false}) // Nicht valide
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT11downloadsUniqueRegular, Level2: ST4monthly, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT11downloadsUniqueRegular, Level2: ST5tree, Level3: RT1json, Active: true})

	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT12downloadsUniqueMachine, Level2: ST1total, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT12downloadsUniqueMachine, Level2: ST2tomonth, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT12downloadsUniqueMachine, Level2: ST3pastdays, Level3: RT1json, Active: false}) // Nicht valide
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT12downloadsUniqueMachine, Level2: ST4monthly, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT12downloadsUniqueMachine, Level2: ST5tree, Level3: RT1json, Active: true})

	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT13citations, Level2: ST1total, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT13citations, Level2: ST2tomonth, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT13citations, Level2: ST3pastdays, Level3: RT1json, Active: false}) // Nicht valide
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT13citations, Level2: ST4monthly, Level3: RT1json, Active: true})
	OneJumpPoints = append(OneJumpPoints, OneJumpPointSet{Level0: MT7makeDataCount, Level1: MDCT13citations, Level2: ST5tree, Level3: RT1json, Active: true})

	//OldOneJumpPointSet[MT1dataverses][MDCT1viewsTotal][ST2_tomonth][RT1json] = true
	//OldOneJumpPointSet[MT1dataverses][MDCT2viewsTotalRegular][ST3_pastdays][RT2csv] = true
	//fmt.Println(OneJumpPointSet)

}

func FilterStacklist(meisleisz []OneJumpPointSet, index int8) (deisleisz []string, activity []bool) {
	switch index {
	case 0:
		for _, v := range meisleisz {
			if !slices.Contains(deisleisz, string(v.Level0)) {
				deisleisz = append(deisleisz, string(v.Level0))
				activity = append(activity, v.Active)
			}
		}
	case 1:
		for _, v := range meisleisz {
			if !slices.Contains(deisleisz, string(v.Level1)) {
				deisleisz = append(deisleisz, string(v.Level1))
				activity = append(activity, v.Active)
			}
		}
	case 2:
		for _, v := range meisleisz {
			if !slices.Contains(deisleisz, string(v.Level2)) {
				deisleisz = append(deisleisz, string(v.Level2))
				activity = append(activity, v.Active)
			}
		}
	case 3:
		for _, v := range meisleisz {
			if !slices.Contains(deisleisz, string(v.Level3)) {
				deisleisz = append(deisleisz, string(v.Level3))
				activity = append(activity, v.Active)
			}
		}
	}

	return
}

type RequestComponentsType struct {
	Level0MetricsType, Level1MetricsDataCountType, Level2SearchType, Level21UserInput, Level3ReturnformatType string
}

/*
func JsonStructSelector[resulttype MonthlyJsonData | TotalJsonData | TreeJsonData | struct{}](bjson []byte) (result resulttype) {
	switch {
	case json.Unmarshal(bjson, &result) == nil:
	case json.Unmarshal(bjson, &result) == nil:
	case json.Unmarshal(bjson, &result) == nil:
	}
	return
}
*/

/*
func MetricsUniversal(server_url, api_token string, rcs RequestComponentsType) {
	var err error
	//var header map[string]string
	header := make(map[string]string)

	if len(api_token) > 0 {
		header["X-Dataverse-key"] = api_token
	}
	if len(rcs.Level3ReturnformatType) > 0 {
		header["Accept"] = string(rcs.Level3ReturnformatType)
	}

	stest := func(s ...string) string {

		if (len(s) > 1 && len(s[0]) > 0) || len(s) == 1 {
			if s[0] == string(ST1total) {
				return ""
			} else {
				return "/" + s[0]
			}
		} else if (len(s) == 2 && len(s[1]) > 0) || (len(s) == 3 && len(s[1]) > 0 && len(s[2]) == 0) {
			return "/" + s[1]
		} else if len(s) == 3 && len(s[1]) > 0 && len(s[2]) > 0 {
			if s[0] == string(ST1total) {
				return ""
			} else if s[1] == string(ST4monthly) {
				return "/" + s[1] // bei Monthly werden erstmal ALLE Datensätze gezogen
			} else {
				return "/" + s[1] + "/" + s[2]
			}
		} else {
			return ""
		}

	}

	log.Println("DEBUG:", server_url+"/api/info/metrics"+
		"/"+rcs.Level0MetricsType+
		stest(rcs.Level1MetricsDataCountType, rcs.Level2SearchType, rcs.Level21UserInput))



	if err != nil {
		log.Fatal(err)
	}

	return
}*/

//func MetricsDataCountType() (response []byte, debug string)

func MetricsTotal(server_url, api_token string, return_format ReturnformatType, mtypeOrMdctypeCombi string) (response []byte, debug string) {
	var err error
	//var header map[string]string
	header := make(map[string]string)

	if len(api_token) > 0 {
		header["X-Dataverse-key"] = api_token
	}
	if len(return_format) > 0 {
		header["Accept"] = string(return_format)
	}

	//log.Println(header)

	response, err, debug = connect.GetRequest(server_url+StaticMetricsAPIbody+mtypeOrMdctypeCombi, map[string]string{}, header)

	if err != nil {
		log.Fatal(err)
	}

	return
}

func MetricsToMonth(server_url, api_token string, return_format ReturnformatType, mtypeOrMdctypeCombi string, timerange time.Time) (response []byte, debug string) {
	var err error
	//var header map[string]string
	header := make(map[string]string)

	if len(api_token) > 0 {
		header["X-Dataverse-key"] = api_token
	}
	if len(return_format) > 0 {
		header["Accept"] = string(return_format)
	}

	//log.Println(header)

	response, err, debug = connect.GetRequest(server_url+StaticMetricsAPIbody+mtypeOrMdctypeCombi+"/toMonth/"+timerange.Format("2006-01"), map[string]string{}, header)

	if err != nil {
		log.Fatal(err)
	}

	return
}

func MetricsPastDays(server_url, api_token string, return_format ReturnformatType, mtypeOrMdctypeCombi string, days int) (response []byte, debug string) {
	var err error
	//var header map[string]string
	header := make(map[string]string)

	if len(api_token) > 0 {
		header["X-Dataverse-key"] = api_token
	}
	if len(return_format) > 0 {
		header["Accept"] = string(return_format)
	}

	//log.Println(header)

	response, err, debug = connect.GetRequest(server_url+StaticMetricsAPIbody+mtypeOrMdctypeCombi+"/pastDays/"+strconv.Itoa(days), map[string]string{}, header)

	if err != nil {
		log.Fatal(err)
	}

	return
}

func MetricsMonthly(server_url, api_token string, return_format ReturnformatType, mtypeOrMdctypeCombi string) (response []byte, debug string) {
	var err error
	//var header map[string]string
	header := make(map[string]string)

	if len(api_token) > 0 {
		header["X-Dataverse-key"] = api_token
	}
	if len(return_format) > 0 {
		header["Accept"] = string(return_format)
	}

	//log.Println(header)
	response, err, debug = connect.GetRequest(server_url+StaticMetricsAPIbody+mtypeOrMdctypeCombi+"/monthly/", map[string]string{}, header)

	if err != nil {
		log.Fatal(err)
	}

	return
}

type MonthlyJsonData struct {
	Status string `json:"status"`
	Data   []struct {
		Date       string `json:"date"`
		Id         int    `json:"id"`
		Pid        string `json:"pid"`
		Counttotal int    `json:"count"`
		Countmonth int    `json:"mount"` //Month Count
		//Intex      int    `json:"intex"` //Integer Index instead of Date
		DoiDoi string `json:"doidoi"` //Added to beautify links
	} `json:"data"`
}

type TotalJsonData struct {
	Status string `json:"status"`
	Data   struct {
		Counttotal int `json:"count"`
	} `json:"data"`
}

type TreeJsonData struct {
	Status string `json:"status"`
	Data   struct {
		Id       int    `json:"id"`
		Ownerid  int    `json:"ownerId"`
		Alias    string `json:"alias"`
		Depth    int    `json:"depth"`
		Name     string `json:"name"`
		Children []struct {
			Id      int    `json:"id"`
			Ownerid int    `json:"ownerId"`
			Alias   string `json:"alias"`
			Depth   int    `json:"depth"`
			Name    string `json:"name"`
		} `json:"children"`
	} `json:"data"`
}

func MetricsReallyMonthly(server_url, api_token string, return_format ReturnformatType, mtypeOrMdctypeCombi string) (response []byte, debug string) {
	response, debug = MetricsMonthly(server_url, api_token, return_format, mtypeOrMdctypeCombi)

	//	var newData map[string]

	res := MonthlyJsonData{}
	json.Unmarshal(response, &res)

	intexmaker := func(s string) (i int) {
		i, _ = strconv.Atoi(s[0:4] + s[5:7])
		return
	}

	//for i, _ := range res.Data {
	//	res.Data[i].Intex = intexmaker(res.Data[i].Date) //Filtere den Bindestrich heraus
	//}

	//sort.Slice(res.Data, func(i, j int) bool { return res.Data[i].Intex > res.Data[j].Intex }) // Sortiere rückwärts
	sort.Slice(res.Data, func(i, j int) bool { return intexmaker(res.Data[i].Date) > intexmaker(res.Data[j].Date) }) // Sortiere rückwärts

	for i, _ := range res.Data {
		if i+1 < len(res.Data) { // Finde heraus, wieviele Werte für speziell diesen Monat gelten
			res.Data[i].Countmonth = res.Data[i].Counttotal - res.Data[i+1].Counttotal
		} else {
			res.Data[i].Countmonth = res.Data[i].Counttotal
		}

		if _, f := strings.CutPrefix(res.Data[i].Pid, "doi:"); f { // Erzeuge gleich einen Link zum Doi
			res.Data[i].DoiDoi = PDPURL + "/file.xhtml?persistentId=" + res.Data[i].Pid
		} else {
			res.Data[i].DoiDoi = ""
		}
	}

	//sort.Slice(res.Data, func(i, j int) bool { return res.Data[i].Intex < res.Data[j].Intex }) // Sortiere wieder vorwärts
	sort.Slice(res.Data, func(i, j int) bool { return intexmaker(res.Data[i].Date) < intexmaker(res.Data[j].Date) }) // Sortiere wieder vorwärts

	//log.Println(res)

	debug += " #enhanced by monthly count (mount)"
	response, _ = json.Marshal(res)
	return
}

func MetricsReallyMonthlySpan(server_url, api_token string, return_format ReturnformatType, mtypeOrMdctypeCombi string, timerange_span [2]time.Time) (response []byte, debug string) {

	response, debug = MetricsReallyMonthly(server_url, api_token, return_format, mtypeOrMdctypeCombi)

	//timerange_span[0].Format("2006-01")
	//timerange_span[1].Format("2006-01")

	//res := monthlyJsonData{}
	var res, res2 MonthlyJsonData
	res2.Status = res.Status

	json.Unmarshal(response, &res)

	for _, v := range res.Data { // Finde heraus, wieviele Werte für speziell diesen Monat gelten
		if func() bool {
			ts, _ := time.Parse("2006-01", v.Date)

			if !ts.Before(timerange_span[0]) && !ts.After(timerange_span[1]) {
				return true
			} else {
				return false
			}
		}() {
			//debug += fmt.Sprintf("gefunden %s", v.Date)
			res2.Data = append(res2.Data, v)
		}
	}

	//debug += fmt.Sprintln(res2)
	//debug += fmt.Sprintln("T E S T")

	response, _ = json.Marshal(res2)
	return
}

func MetricsTree(server_url, api_token string, return_format ReturnformatType, timerange time.Time) (response []byte, debug string) {
	var err error
	var header map[string]string
	header = make(map[string]string)

	if len(api_token) > 0 {
		header["X-Dataverse-key"] = api_token
	}
	if len(return_format) > 0 {
		header["Accept"] = string(return_format)
	}

	//log.Println(header)

	response, err, debug = connect.GetRequest(server_url+"/api/info/metrics/tree"+func() string {
		if !timerange.IsZero() {
			return "/toMonth/" + timerange.Format("2006-01")
		} else {
			return ""
		}
	}(), map[string]string{}, header)

	if err != nil {
		log.Fatal(err)
	}

	return
}

/*
func ListUsers(server_url, api_token string, sorted bool) string {
	response, err, _ := connect.GetRequest(server_url+"/api/admin/list-users"+func(s bool) string {
		if s {
			return "?sortKey=createdtime"
		} else {
			return ""
		}
	}(sorted), map[string]string{}, map[string]string{"X-Dataverse-key": api_token})

	if err != nil {
		log.Fatal(err)
	}

	return (fmt.Sprintf("%s", response))

	//curl -H "X-Dataverse-key:$API_TOKEN" $SERVER_URL/api/admin/list-users

	//# sort by createdtime (the creation time of the account)
	//#curl -H "X-Dataverse-key:$API_TOKEN" "$SERVER_URL/api/admin/list-users?sortKey=createdtime"
}

func ListUser(server_url, api_token, id string) string {
	response, err, _ := connect.GetRequest(server_url+"/api/admin/authenticatedUsers/"+id, map[string]string{}, map[string]string{"X-Dataverse-key": api_token})

	if err != nil {
		log.Fatal(err)
	}

	return (fmt.Sprintf("%s", response))
}
*/

/*
func ToggleSuperuser(server_url, api_token, id string) string {
	response, err := connect.PostRequest(server_url+"/api/admin/superuser/"+id+"", map[string]string{}, map[string]string{"X-Dataverse-key": api_token})

	if err != nil {
		log.Fatal(err)
	}

	return (fmt.Sprintf("%s", response))
}
*/

/*
func CreateAuthenticatedUser(server_url, api_token, params string) string {
	response, err := connect.PostRequestB(server_url+"/api/admin/authenticatedUsers", []byte(params), map[string]string{"X-Dataverse-key": api_token})

	if err != nil {
		log.Fatal(err)
	}

	return (fmt.Sprintf("%s", response))
}
*/
