/*
Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments
Copyright (C) ITsysCOM GmbH

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>
*/
package config

import (
	"encoding/json"
	"fmt"
	"reflect"
	"testing"
	"time"

	"github.com/cgrates/birpc/context"
	"github.com/cgrates/cgrates/utils"
	"github.com/cgrates/rpcclient"
)

func TestDfGeneralJsonCfg(t *testing.T) {
	eCfg := &GeneralJsonCfg{
		Node_id:                utils.StringPointer(""),
		Rounding_decimals:      utils.IntPointer(5),
		Dbdata_encoding:        utils.StringPointer("*msgpack"),
		Tpexport_dir:           utils.StringPointer("/var/spool/cgrates/tpe"),
		Default_request_type:   utils.StringPointer(utils.MetaRated),
		Default_category:       utils.StringPointer("call"),
		Default_tenant:         utils.StringPointer("cgrates.org"),
		Default_caching:        utils.StringPointer(utils.MetaReload),
		Caching_delay:          utils.StringPointer("0s"),
		Default_timezone:       utils.StringPointer("Local"),
		Connect_attempts:       utils.IntPointer(5),
		Reconnects:             utils.IntPointer(-1),
		Max_reconnect_interval: utils.StringPointer(utils.EmptyString),
		Connect_timeout:        utils.StringPointer("1s"),
		Reply_timeout:          utils.StringPointer("2s"),
		Locking_timeout:        utils.StringPointer("0"),
		Digest_separator:       utils.StringPointer(","),
		Digest_equal:           utils.StringPointer(":"),
		Max_parallel_conns:     utils.IntPointer(100),
		Decimal_max_scale:      utils.IntPointer(0),
		Decimal_min_scale:      utils.IntPointer(0),
		Decimal_precision:      utils.IntPointer(0),
		Decimal_rounding_mode:  utils.StringPointer("*toNearestEven"),
		Opts:                   &GeneralOptsJson{},
	}
	dfCgrJSONCfg, err := NewCgrJsonCfgFromBytes([]byte(CGRATES_CFG_JSON))
	if err != nil {
		t.Error(err)
	}
	gCfg := new(GeneralJsonCfg)
	if err := dfCgrJSONCfg.GetSection(context.Background(), GeneralJSON, gCfg); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, gCfg) {
		t.Errorf("expecting: %s, \nreceived: %s", utils.ToIJSON(eCfg), utils.ToIJSON(gCfg))
	}
}

func TestDfCoreSJsonCfg(t *testing.T) {
	eCfg := &CoreSJsonCfg{
		Caps:                utils.IntPointer(0),
		Caps_strategy:       utils.StringPointer(utils.MetaBusy),
		Caps_stats_interval: utils.StringPointer("0"),
		Ees_conns:           utils.SliceStringPointer([]string{}),
		Shutdown_timeout:    utils.StringPointer("1s"),
	}
	dfCgrJSONCfg, err := NewCgrJsonCfgFromBytes([]byte(CGRATES_CFG_JSON))
	if err != nil {
		t.Error(err)
	}
	gCfg := new(CoreSJsonCfg)
	if err := dfCgrJSONCfg.GetSection(context.Background(), CoreSJSON, gCfg); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, gCfg) {
		t.Errorf("expecting: %s, \nreceived: %s", utils.ToIJSON(eCfg), utils.ToIJSON(gCfg))
	}
}

func TestCacheJsonCfg(t *testing.T) {
	eCfg := &CacheJsonCfg{
		Partitions: map[string]*CacheParamJsonCfg{
			utils.CacheResourceProfiles: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false),
				Precache: utils.BoolPointer(false), Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheResources: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false),
				Precache: utils.BoolPointer(false), Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheEventResources: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false),
				Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheIPProfiles: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false),
				Precache: utils.BoolPointer(false), Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheIPAllocations: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false),
				Precache: utils.BoolPointer(false), Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheEventIPs: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false),
				Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheStatQueueProfiles: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false),
				Precache: utils.BoolPointer(false), Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheStatQueues: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false),
				Precache: utils.BoolPointer(false), Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheThresholdProfiles: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false),
				Precache: utils.BoolPointer(false), Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheThresholds: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false),
				Precache: utils.BoolPointer(false), Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheTrendProfiles: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false),
				Precache: utils.BoolPointer(false), Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheTrends: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false),
				Precache: utils.BoolPointer(false), Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheFilters: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false),
				Precache: utils.BoolPointer(false), Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheRouteProfiles: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false),
				Precache: utils.BoolPointer(false), Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheAttributeProfiles: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false),
				Precache: utils.BoolPointer(false), Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheChargerProfiles: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false),
				Precache: utils.BoolPointer(false), Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheRateProfiles: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false),
				Precache: utils.BoolPointer(false), Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheActionProfiles: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false),
				Precache: utils.BoolPointer(false), Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheAccounts: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false),
				Precache: utils.BoolPointer(false), Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheResourceFilterIndexes: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false),
				Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheIPFilterIndexes: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false),
				Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheStatFilterIndexes: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false),
				Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheThresholdFilterIndexes: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false),
				Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheRouteFilterIndexes: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false),
				Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheAttributeFilterIndexes: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false),
				Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheChargerFilterIndexes: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false),
				Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheRateProfilesFilterIndexes: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false),
				Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheRateFilterIndexes: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false),
				Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheActionProfilesFilterIndexes: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false),
				Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheAccountsFilterIndexes: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false),
				Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheReverseFilterIndexes: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false),
				Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheDiameterMessages: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer("3h"), Static_ttl: utils.BoolPointer(false),
				Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheRadiusPackets: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer("3h"), Static_ttl: utils.BoolPointer(false),
				Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheRPCResponses: {Limit: utils.IntPointer(0),
				Ttl: utils.StringPointer("2s"), Static_ttl: utils.BoolPointer(false),
				Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheClosedSessions: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer("10s"), Static_ttl: utils.BoolPointer(false),
				Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheEventCharges: {Limit: utils.IntPointer(0),
				Ttl: utils.StringPointer("10s"), Static_ttl: utils.BoolPointer(false),
				Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheCDRIDs: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer("10m"), Static_ttl: utils.BoolPointer(false),
				Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheLoadIDs: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false),
				Precache: utils.BoolPointer(false), Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheRankingProfiles: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false), Precache: utils.BoolPointer(false),
				Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheRankings: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false), Precache: utils.BoolPointer(false),
				Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheRPCConnections: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false),
				Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheUCH: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer("3h"), Static_ttl: utils.BoolPointer(false),
				Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheSTIR: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer("3h"), Static_ttl: utils.BoolPointer(false),
				Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheCapsEvents: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false),
				Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false),
			},
			utils.MetaSentryPeer: {
				Limit: utils.IntPointer(-1),
				Ttl:   utils.StringPointer("24h"), Static_ttl: utils.BoolPointer(true),
				Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false),
			},
			utils.MetaAPIBan: {Limit: utils.IntPointer(-1),
				Ttl: utils.StringPointer("2m"), Static_ttl: utils.BoolPointer(false),
				Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
			utils.CacheReplicationHosts: {Limit: utils.IntPointer(0),
				Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false),
				Remote: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)},
		},
		Replication_conns: &[]string{},
		Remote_conns:      &[]string{},
	}
	dfCgrJSONCfg, err := NewCgrJsonCfgFromBytes([]byte(CGRATES_CFG_JSON))
	if err != nil {
		t.Error(err)
	}

	gCfg := new(CacheJsonCfg)
	if err := dfCgrJSONCfg.GetSection(context.Background(), CacheJSON, gCfg); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, gCfg) {
		t.Errorf("expected: %s\n, received: %s", utils.ToJSON(eCfg), utils.ToJSON(gCfg))
	}
}

func TestDfListenJsonCfg(t *testing.T) {
	eCfg := &ListenJsonCfg{
		Rpc_json:     utils.StringPointer("127.0.0.1:2012"),
		Rpc_gob:      utils.StringPointer("127.0.0.1:2013"),
		Http:         utils.StringPointer("127.0.0.1:2080"),
		Rpc_json_tls: utils.StringPointer("127.0.0.1:2022"),
		Rpc_gob_tls:  utils.StringPointer("127.0.0.1:2023"),
		Http_tls:     utils.StringPointer("127.0.0.1:2280"),
	}
	dfCgrJSONCfg, err := NewCgrJsonCfgFromBytes([]byte(CGRATES_CFG_JSON))
	if err != nil {
		t.Error(err)
	}
	cfg := new(ListenJsonCfg)
	if err := dfCgrJSONCfg.GetSection(context.Background(), ListenJSON, cfg); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Error("Received: ", cfg)
	}
}

func TestDfDataDbJsonCfg(t *testing.T) {
	eCfg := &DbJsonCfg{
		Db_conns: DbConnsJson{
			utils.MetaDefault: &DbConnJson{
				Db_type:               utils.StringPointer(utils.MetaInternal),
				Db_host:               utils.StringPointer(utils.EmptyString),
				Db_port:               utils.IntPointer(0),
				Db_name:               utils.StringPointer(utils.EmptyString),
				Db_user:               utils.StringPointer(utils.EmptyString),
				Db_password:           utils.StringPointer(utils.EmptyString),
				String_indexed_fields: &[]string{},
				Prefix_indexed_fields: &[]string{},
				Replication_conns:     &[]string{},
				Remote_conns:          &[]string{},
				Replication_filtered:  utils.BoolPointer(false),
				Remote_conn_id:        utils.StringPointer(utils.EmptyString),
				Replication_cache:     utils.StringPointer(utils.EmptyString),
				RplFailedDir:          utils.StringPointer(utils.EmptyString),
				RplInterval:           utils.StringPointer(utils.EmptyString),
				Opts: &DBOptsJson{
					InternalDBDumpPath:        utils.StringPointer("/var/lib/cgrates/internal_db/db"),
					InternalDBBackupPath:      utils.StringPointer("/var/lib/cgrates/internal_db/backup/db"),
					InternalDBStartTimeout:    utils.StringPointer("5m"),
					InternalDBDumpInterval:    utils.StringPointer("1m"),
					InternalDBRewriteInterval: utils.StringPointer("1h"),
					InternalDBFileSizeLimit:   utils.StringPointer("1GB"),
					RedisMaxConns:             utils.IntPointer(10),
					RedisConnectAttempts:      utils.IntPointer(20),
					RedisCACertificate:        utils.StringPointer(utils.EmptyString),
					RedisClientCertificate:    utils.StringPointer(utils.EmptyString),
					RedisClientKey:            utils.StringPointer(utils.EmptyString),
					RedisCluster:              utils.BoolPointer(false),
					RedisTLS:                  utils.BoolPointer(false),
					RedisSentinel:             utils.StringPointer(utils.EmptyString),
					MongoQueryTimeout:         utils.StringPointer("10s"),
					MongoConnScheme:           utils.StringPointer("mongodb"),
					RedisClusterOndownDelay:   utils.StringPointer("0"),
					RedisConnectTimeout:       utils.StringPointer("0"),
					RedisReadTimeout:          utils.StringPointer("0"),
					RedisWriteTimeout:         utils.StringPointer("0"),
					RedisClusterSync:          utils.StringPointer("5s"),
					RedisPoolPipelineWindow:   utils.StringPointer("150µs"),
					RedisPoolPipelineLimit:    utils.IntPointer(0),
					SQLMaxOpenConns:           utils.IntPointer(100),
					SQLMaxIdleConns:           utils.IntPointer(10),
					SQLLogLevel:               utils.IntPointer(3),
					SQLConnMaxLifetime:        utils.StringPointer("0"),
					MYSQLDSNParams:            map[string]string{},
					PgSSLMode:                 utils.StringPointer("disable"),
					MySQLLocation:             utils.StringPointer("Local"),
				},
			},
		},

		Items: map[string]*ItemOptsJson{
			utils.CacheAccounts: {
				Ttl:        utils.StringPointer(utils.EmptyString),
				Static_ttl: utils.BoolPointer(false),
				Limit:      utils.IntPointer(-1),
				Replicate:  utils.BoolPointer(false),
				Remote:     utils.BoolPointer(false),
				DbConn:     utils.StringPointer(utils.MetaDefault),
			},
			utils.CacheResourceProfiles: {
				Ttl:        utils.StringPointer(utils.EmptyString),
				Static_ttl: utils.BoolPointer(false),
				Limit:      utils.IntPointer(-1),
				Replicate:  utils.BoolPointer(false),
				Remote:     utils.BoolPointer(false),
				DbConn:     utils.StringPointer(utils.MetaDefault),
			},
			utils.CacheIPProfiles: {
				Ttl:        utils.StringPointer(utils.EmptyString),
				Static_ttl: utils.BoolPointer(false),
				Limit:      utils.IntPointer(-1),
				Replicate:  utils.BoolPointer(false),
				Remote:     utils.BoolPointer(false),
				DbConn:     utils.StringPointer(utils.MetaDefault),
			},
			utils.CacheStatQueues: {
				Ttl:        utils.StringPointer(utils.EmptyString),
				Static_ttl: utils.BoolPointer(false),
				Limit:      utils.IntPointer(-1),
				Replicate:  utils.BoolPointer(false),
				Remote:     utils.BoolPointer(false),
				DbConn:     utils.StringPointer(utils.MetaDefault),
			},
			utils.CacheResources: {
				Ttl:        utils.StringPointer(utils.EmptyString),
				Static_ttl: utils.BoolPointer(false),
				Limit:      utils.IntPointer(-1),
				Replicate:  utils.BoolPointer(false),
				Remote:     utils.BoolPointer(false),
				DbConn:     utils.StringPointer(utils.MetaDefault),
			},
			utils.CacheIPAllocations: {
				Ttl:        utils.StringPointer(utils.EmptyString),
				Static_ttl: utils.BoolPointer(false),
				Limit:      utils.IntPointer(-1),
				Replicate:  utils.BoolPointer(false),
				Remote:     utils.BoolPointer(false),
				DbConn:     utils.StringPointer(utils.MetaDefault),
			},
			utils.CacheStatQueueProfiles: {
				Ttl:        utils.StringPointer(utils.EmptyString),
				Static_ttl: utils.BoolPointer(false),
				Limit:      utils.IntPointer(-1),
				Replicate:  utils.BoolPointer(false),
				Remote:     utils.BoolPointer(false),
				DbConn:     utils.StringPointer(utils.MetaDefault),
			},
			utils.CacheThresholds: {
				Ttl:        utils.StringPointer(utils.EmptyString),
				Static_ttl: utils.BoolPointer(false),
				Limit:      utils.IntPointer(-1),
				Replicate:  utils.BoolPointer(false),
				Remote:     utils.BoolPointer(false),
				DbConn:     utils.StringPointer(utils.MetaDefault),
			},
			utils.CacheTrends: {
				Ttl:        utils.StringPointer(utils.EmptyString),
				Static_ttl: utils.BoolPointer(false),
				Limit:      utils.IntPointer(-1),
				Replicate:  utils.BoolPointer(false),
				Remote:     utils.BoolPointer(false),
				DbConn:     utils.StringPointer(utils.MetaDefault),
			},
			utils.CacheThresholdProfiles: {
				Ttl:        utils.StringPointer(utils.EmptyString),
				Static_ttl: utils.BoolPointer(false),
				Limit:      utils.IntPointer(-1),
				Replicate:  utils.BoolPointer(false),
				Remote:     utils.BoolPointer(false),
				DbConn:     utils.StringPointer(utils.MetaDefault),
			},
			utils.CacheFilters: {
				Ttl:        utils.StringPointer(utils.EmptyString),
				Static_ttl: utils.BoolPointer(false),
				Limit:      utils.IntPointer(-1),
				Replicate:  utils.BoolPointer(false),
				Remote:     utils.BoolPointer(false),
				DbConn:     utils.StringPointer(utils.MetaDefault),
			},
			utils.CacheRouteProfiles: {
				Ttl:        utils.StringPointer(utils.EmptyString),
				Static_ttl: utils.BoolPointer(false),
				Limit:      utils.IntPointer(-1),
				Replicate:  utils.BoolPointer(false),
				Remote:     utils.BoolPointer(false),
				DbConn:     utils.StringPointer(utils.MetaDefault),
			},
			utils.CacheAttributeProfiles: {
				Ttl:        utils.StringPointer(utils.EmptyString),
				Static_ttl: utils.BoolPointer(false),
				Limit:      utils.IntPointer(-1),
				Replicate:  utils.BoolPointer(false),
				Remote:     utils.BoolPointer(false),
				DbConn:     utils.StringPointer(utils.MetaDefault),
			},
			utils.CacheRateProfiles: {
				Ttl:        utils.StringPointer(utils.EmptyString),
				Static_ttl: utils.BoolPointer(false),
				Limit:      utils.IntPointer(-1),
				Replicate:  utils.BoolPointer(false),
				Remote:     utils.BoolPointer(false),
				DbConn:     utils.StringPointer(utils.MetaDefault),
			},
			utils.CacheActionProfiles: {
				Ttl:        utils.StringPointer(utils.EmptyString),
				Static_ttl: utils.BoolPointer(false),
				Limit:      utils.IntPointer(-1),
				Replicate:  utils.BoolPointer(false),
				Remote:     utils.BoolPointer(false),
				DbConn:     utils.StringPointer(utils.MetaDefault),
			},
			utils.CacheChargerProfiles: {
				Ttl:        utils.StringPointer(utils.EmptyString),
				Static_ttl: utils.BoolPointer(false),
				Limit:      utils.IntPointer(-1),
				Replicate:  utils.BoolPointer(false),
				Remote:     utils.BoolPointer(false),
				DbConn:     utils.StringPointer(utils.MetaDefault),
			},
			utils.CacheLoadIDs: {
				Ttl:        utils.StringPointer(utils.EmptyString),
				Static_ttl: utils.BoolPointer(false),
				Limit:      utils.IntPointer(-1),
				Replicate:  utils.BoolPointer(false),
				Remote:     utils.BoolPointer(false),
				DbConn:     utils.StringPointer(utils.MetaDefault),
			},
			utils.CacheResourceFilterIndexes: {
				Ttl:        utils.StringPointer(utils.EmptyString),
				Static_ttl: utils.BoolPointer(false),
				Limit:      utils.IntPointer(-1),
				Replicate:  utils.BoolPointer(false),
				Remote:     utils.BoolPointer(false),
				DbConn:     utils.StringPointer(utils.MetaDefault),
			},
			utils.CacheIPFilterIndexes: {
				Ttl:        utils.StringPointer(utils.EmptyString),
				Static_ttl: utils.BoolPointer(false),
				Limit:      utils.IntPointer(-1),
				Replicate:  utils.BoolPointer(false),
				Remote:     utils.BoolPointer(false),
				DbConn:     utils.StringPointer(utils.MetaDefault),
			},
			utils.CacheStatFilterIndexes: {
				Ttl:        utils.StringPointer(utils.EmptyString),
				Static_ttl: utils.BoolPointer(false),
				Limit:      utils.IntPointer(-1),
				Replicate:  utils.BoolPointer(false),
				Remote:     utils.BoolPointer(false),
				DbConn:     utils.StringPointer(utils.MetaDefault),
			},
			utils.CacheThresholdFilterIndexes: {
				Ttl:        utils.StringPointer(utils.EmptyString),
				Static_ttl: utils.BoolPointer(false),
				Limit:      utils.IntPointer(-1),
				Replicate:  utils.BoolPointer(false),
				Remote:     utils.BoolPointer(false),
				DbConn:     utils.StringPointer(utils.MetaDefault),
			},
			utils.CacheRouteFilterIndexes: {
				Ttl:        utils.StringPointer(utils.EmptyString),
				Static_ttl: utils.BoolPointer(false),
				Limit:      utils.IntPointer(-1),
				Replicate:  utils.BoolPointer(false),
				Remote:     utils.BoolPointer(false),
				DbConn:     utils.StringPointer(utils.MetaDefault),
			},
			utils.CacheAttributeFilterIndexes: {
				Ttl:        utils.StringPointer(utils.EmptyString),
				Static_ttl: utils.BoolPointer(false),
				Limit:      utils.IntPointer(-1),
				Replicate:  utils.BoolPointer(false),
				Remote:     utils.BoolPointer(false),
				DbConn:     utils.StringPointer(utils.MetaDefault),
			},
			utils.CacheChargerFilterIndexes: {
				Ttl:        utils.StringPointer(utils.EmptyString),
				Static_ttl: utils.BoolPointer(false),
				Limit:      utils.IntPointer(-1),
				Replicate:  utils.BoolPointer(false),
				Remote:     utils.BoolPointer(false),
				DbConn:     utils.StringPointer(utils.MetaDefault),
			},
			utils.CacheRateProfilesFilterIndexes: {
				Ttl:        utils.StringPointer(utils.EmptyString),
				Static_ttl: utils.BoolPointer(false),
				Limit:      utils.IntPointer(-1),
				Replicate:  utils.BoolPointer(false),
				Remote:     utils.BoolPointer(false),
				DbConn:     utils.StringPointer(utils.MetaDefault),
			},
			utils.CacheActionProfilesFilterIndexes: {
				Ttl:        utils.StringPointer(utils.EmptyString),
				Static_ttl: utils.BoolPointer(false),
				Limit:      utils.IntPointer(-1),
				Replicate:  utils.BoolPointer(false),
				Remote:     utils.BoolPointer(false),
				DbConn:     utils.StringPointer(utils.MetaDefault),
			},
			utils.CacheAccountsFilterIndexes: {
				Ttl:        utils.StringPointer(utils.EmptyString),
				Static_ttl: utils.BoolPointer(false),
				Limit:      utils.IntPointer(-1),
				Replicate:  utils.BoolPointer(false),
				Remote:     utils.BoolPointer(false),
				DbConn:     utils.StringPointer(utils.MetaDefault),
			},
			utils.CacheVersions: {
				Ttl:        utils.StringPointer(utils.EmptyString),
				Static_ttl: utils.BoolPointer(false),
				Limit:      utils.IntPointer(-1),
				Replicate:  utils.BoolPointer(false),
				Remote:     utils.BoolPointer(false),
				DbConn:     utils.StringPointer(utils.MetaDefault),
			},
			utils.CacheReverseFilterIndexes: {
				Ttl:        utils.StringPointer(utils.EmptyString),
				Static_ttl: utils.BoolPointer(false),
				Limit:      utils.IntPointer(-1),
				Replicate:  utils.BoolPointer(false),
				Remote:     utils.BoolPointer(false),
				DbConn:     utils.StringPointer(utils.MetaDefault),
			},
			utils.CacheRankingProfiles: {
				Ttl:        utils.StringPointer(utils.EmptyString),
				Static_ttl: utils.BoolPointer(false),
				Limit:      utils.IntPointer(-1),
				Replicate:  utils.BoolPointer(false),
				Remote:     utils.BoolPointer(false),
				DbConn:     utils.StringPointer(utils.MetaDefault),
			},
			utils.CacheRankings: {
				Ttl:        utils.StringPointer(utils.EmptyString),
				Static_ttl: utils.BoolPointer(false),
				Limit:      utils.IntPointer(-1),
				Replicate:  utils.BoolPointer(false),
				Remote:     utils.BoolPointer(false),
				DbConn:     utils.StringPointer(utils.MetaDefault),
			},
			utils.CacheTrendProfiles: {
				Ttl:        utils.StringPointer(utils.EmptyString),
				Static_ttl: utils.BoolPointer(false),
				Limit:      utils.IntPointer(-1),
				Replicate:  utils.BoolPointer(false),
				Remote:     utils.BoolPointer(false),
				DbConn:     utils.StringPointer(utils.MetaDefault),
			},
			utils.CacheRateFilterIndexes: {
				Ttl:        utils.StringPointer(utils.EmptyString),
				Static_ttl: utils.BoolPointer(false),
				Limit:      utils.IntPointer(-1),
				Replicate:  utils.BoolPointer(false),
				Remote:     utils.BoolPointer(false),
				DbConn:     utils.StringPointer(utils.MetaDefault),
			},
			utils.MetaCDRs: {
				Ttl:        utils.StringPointer(utils.EmptyString),
				Static_ttl: utils.BoolPointer(false),
				Limit:      utils.IntPointer(-1),
				Replicate:  utils.BoolPointer(false),
				Remote:     utils.BoolPointer(false),
				DbConn:     utils.StringPointer(utils.MetaDefault),
			},
		},
	}
	dfCgrJSONCfg, err := NewCgrJsonCfgFromBytes([]byte(CGRATES_CFG_JSON))
	if err != nil {
		t.Error(err)
	}
	cfg := new(DbJsonCfg)
	if err := dfCgrJSONCfg.GetSection(context.Background(), DBJSON, cfg); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Errorf("expecting: %s, \nreceived: %s", utils.ToJSON(eCfg), utils.ToJSON(cfg))
	}
}

func TestDfCdrsJsonCfg(t *testing.T) {
	eCfg := &CdrsJsonCfg{
		Enabled:              utils.BoolPointer(false),
		Extra_fields:         &[]string{},
		Session_cost_retries: utils.IntPointer(5),
		Chargers_conns:       &[]string{},
		Attributes_conns:     &[]string{},
		Thresholds_conns:     &[]string{},
		Stats_conns:          &[]string{},
		Online_cdr_exports:   &[]string{},
		Actions_conns:        &[]string{},
		Ees_conns:            &[]string{},
		Rates_conns:          &[]string{},
		Accounts_conns:       &[]string{},
		Opts:                 &CdrsOptsJson{},
	}
	dfCgrJSONCfg, err := NewCgrJsonCfgFromBytes([]byte(CGRATES_CFG_JSON))
	if err != nil {
		t.Error(err)
	}
	cfg := new(CdrsJsonCfg)
	if err := dfCgrJSONCfg.GetSection(context.Background(), CDRsJSON, cfg); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Errorf("Received: %+v", utils.ToJSON(cfg))
	}
}

func TestSmgJsonCfg(t *testing.T) {
	eCfg := &SessionSJsonCfg{
		Enabled:             utils.BoolPointer(false),
		ListenBiJSON:        utils.StringPointer("127.0.0.1:2014"),
		ListenBiGob:         utils.StringPointer(""),
		ChargerSConns:       &[]string{},
		CDRsConns:           &[]string{},
		ResourceSConns:      &[]string{},
		IPsConns:            &[]string{},
		ThresholdSConns:     &[]string{},
		StatSConns:          &[]string{},
		RouteSConns:         &[]string{},
		AttributeSConns:     &[]string{},
		ActionSConns:        &[]string{},
		RateSConns:          &[]string{},
		AccountSConns:       &[]string{},
		ReplicationConns:    &[]string{},
		StoreSCosts:         utils.BoolPointer(false),
		SessionIndexes:      &[]string{},
		ClientProtocol:      utils.Float64Pointer(1.0),
		ChannelSyncInterval: utils.StringPointer("0"),
		TerminateAttempts:   utils.IntPointer(5),
		AlterableFields:     &[]string{},
		DefaultUsage: map[string]string{
			utils.MetaAny:   "3h",
			utils.MetaVoice: "3h",
			utils.MetaData:  "1048576",
			utils.MetaSMS:   "1",
		},
		Stir: &STIRJsonCfg{
			Allowed_attest:      &[]string{utils.MetaAny},
			Payload_maxduration: utils.StringPointer("-1"),
			Default_attest:      utils.StringPointer("A"),
			Privatekey_path:     utils.StringPointer(""),
			Publickey_path:      utils.StringPointer(""),
		},
		Opts: &SessionsOptsJson{},
	}
	dfCgrJSONCfg, err := NewCgrJsonCfgFromBytes([]byte(CGRATES_CFG_JSON))
	if err != nil {
		t.Error(err)
	}
	cfg := new(SessionSJsonCfg)
	if err := dfCgrJSONCfg.GetSection(context.Background(), SessionSJSON, cfg); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Errorf("Expected %v \n but Received \n %v ", utils.ToJSON(eCfg), utils.ToJSON(cfg))
	}
}

func TestFsAgentJsonCfg(t *testing.T) {
	eCfg := &FreeswitchAgentJsonCfg{
		Enabled:                utils.BoolPointer(false),
		SessionSConns:          &[]string{rpcclient.BiRPCInternal},
		SubscribePark:          utils.BoolPointer(true),
		CreateCDR:              utils.BoolPointer(false),
		ExtraFields:            &[]string{},
		LowBalanceAnnFile:      utils.StringPointer(""),
		EmptyBalanceContext:    utils.StringPointer(""),
		EmptyBalanceAnnFile:    utils.StringPointer(""),
		MaxWaitConnection:      utils.StringPointer("2s"),
		ActiveSessionDelimiter: utils.StringPointer(","),
		EventSocketConns: &[]*FsConnJsonCfg{
			{
				Address:              utils.StringPointer("127.0.0.1:8021"),
				Password:             utils.StringPointer("ClueCon"),
				Reconnects:           utils.IntPointer(5),
				MaxReconnectInterval: utils.StringPointer(utils.EmptyString),
				ReplyTimeout:         utils.StringPointer("1m"),
				Alias:                utils.StringPointer(""),
			}},
	}
	dfCgrJSONCfg, err := NewCgrJsonCfgFromBytes([]byte(CGRATES_CFG_JSON))
	if err != nil {
		t.Error(err)
	}
	cfg := new(FreeswitchAgentJsonCfg)
	if err := dfCgrJSONCfg.GetSection(context.Background(), FreeSWITCHAgentJSON, cfg); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Error("Received: ", cfg)
	}
}

func TestKamAgentJsonCfg(t *testing.T) {
	eCfg := &KamAgentJsonCfg{
		Enabled:        utils.BoolPointer(false),
		Sessions_conns: &[]string{rpcclient.BiRPCInternal},
		Create_cdr:     utils.BoolPointer(false),
		Evapi_conns: &[]*KamConnJsonCfg{
			{
				Address:                utils.StringPointer("127.0.0.1:8448"),
				Reconnects:             utils.IntPointer(5),
				Max_reconnect_interval: utils.StringPointer(utils.EmptyString),
			},
		},
		Timezone: utils.StringPointer(utils.EmptyString),
	}
	dfCgrJSONCfg, err := NewCgrJsonCfgFromBytes([]byte(CGRATES_CFG_JSON))
	if err != nil {
		t.Error(err)
	}
	cfg := new(KamAgentJsonCfg)
	if err := dfCgrJSONCfg.GetSection(context.Background(), KamailioAgentJSON, cfg); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Errorf("Expecting: %s \n, received: %s: ",
			utils.ToJSON(eCfg), utils.ToJSON(cfg))
	}
}

func TestAsteriskAgentJsonCfg(t *testing.T) {
	eCfg := &AsteriskAgentJsonCfg{
		Enabled:        utils.BoolPointer(false),
		Sessions_conns: &[]string{rpcclient.BiRPCInternal},
		Create_cdr:     utils.BoolPointer(false),
		Asterisk_conns: &[]*AstConnJsonCfg{
			{
				Address:                utils.StringPointer("127.0.0.1:8088"),
				User:                   utils.StringPointer("cgrates"),
				Password:               utils.StringPointer("CGRateS.org"),
				Max_reconnect_interval: utils.StringPointer(utils.EmptyString),
				Connect_attempts:       utils.IntPointer(3),
				Reconnects:             utils.IntPointer(5),
			},
		},
	}
	dfCgrJSONCfg, err := NewCgrJsonCfgFromBytes([]byte(CGRATES_CFG_JSON))
	if err != nil {
		t.Error(err)
	}
	cfg := new(AsteriskAgentJsonCfg)
	if err := dfCgrJSONCfg.GetSection(context.Background(), AsteriskAgentJSON, cfg); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Errorf("Expecting: %s, received: %s ", utils.ToJSON(eCfg), utils.ToJSON(cfg))
	}
}

func TestDiameterAgentJsonCfg(t *testing.T) {
	eCfg := &DiameterAgentJsonCfg{
		Enabled:                 utils.BoolPointer(false),
		Listen:                  utils.StringPointer("127.0.0.1:3868"),
		ListenNet:               utils.StringPointer(utils.TCP),
		DictionariesPath:        utils.StringPointer("/usr/share/cgrates/diameter/dict/"),
		CEApplications:          nil,
		SessionSConns:           &[]string{rpcclient.BiRPCInternal},
		StatSConns:              &[]string{},
		ThresholdSConns:         &[]string{},
		ConnStatusStatQueueIDs:  &[]string{},
		ConnStatusThresholdIDs:  &[]string{},
		OriginHost:              utils.StringPointer("CGR-DA"),
		OriginRealm:             utils.StringPointer("cgrates.org"),
		VendorID:                utils.IntPointer(0),
		ProductName:             utils.StringPointer("CGRateS"),
		SyncedConnRequests:      utils.BoolPointer(false),
		ASRTemplate:             utils.StringPointer(""),
		RARTemplate:             utils.StringPointer(""),
		ForcedDisconnect:        utils.StringPointer(utils.MetaNone),
		ConnHealthCheckInterval: utils.StringPointer("0"),
		RequestProcessors:       &[]*ReqProcessorJsnCfg{},
	}
	dfCgrJSONCfg, err := NewCgrJsonCfgFromBytes([]byte(CGRATES_CFG_JSON))
	if err != nil {
		t.Error(err)
	}
	cfg := new(DiameterAgentJsonCfg)
	if err := dfCgrJSONCfg.GetSection(context.Background(), DiameterAgentJSON, cfg); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Errorf("expecting: %s, \n\nreceived: %s", utils.ToJSON(eCfg), utils.ToJSON(cfg))
	}
}

func TestRadiusAgentJsonCfg(t *testing.T) {
	eCfg := &RadiusAgentJsonCfg{
		Enabled: utils.BoolPointer(false),
		Listeners: &[]*RadiusListenerJsonCfg{
			{
				Network:     utils.StringPointer("udp"),
				AuthAddress: utils.StringPointer("127.0.0.1:1812"),
				AcctAddress: utils.StringPointer("127.0.0.1:1813"),
			},
		},
		ClientSecrets: map[string]string{
			utils.MetaDefault: "CGRateS.org",
		},
		ClientDictionaries: map[string][]string{
			utils.MetaDefault: {"/usr/share/cgrates/radius/dict/"},
		},
		ClientDaAddresses: map[string]DAClientOptsJson{},
		SessionSConns:     &[]string{utils.MetaInternal},
		StatSConns:        &[]string{},
		ThresholdSConns:   &[]string{},
		DMRTemplate:       utils.StringPointer(utils.MetaDMR),
		CoATemplate:       utils.StringPointer(utils.MetaCoA),
		RequestsCacheKey:  utils.StringPointer(""),
		RequestProcessors: &[]*ReqProcessorJsnCfg{},
	}
	dfCgrJSONCfg, err := NewCgrJsonCfgFromBytes([]byte(CGRATES_CFG_JSON))
	if err != nil {
		t.Error(err)
	}
	cfg := new(RadiusAgentJsonCfg)
	if err := dfCgrJSONCfg.GetSection(context.Background(), RadiusAgentJSON, cfg); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Errorf("Received: %+v", utils.ToJSON(cfg))
	}
}

func TestHttpAgentJsonCfg(t *testing.T) {
	eCfg := &[]*HttpAgentJsonCfg{}
	dfCgrJSONCfg, err := NewCgrJsonCfgFromBytes([]byte(CGRATES_CFG_JSON))
	if err != nil {
		t.Error(err)
	}
	cfg := new([]*HttpAgentJsonCfg)
	if err := dfCgrJSONCfg.GetSection(context.Background(), HTTPAgentJSON, cfg); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Errorf("expecting: %+v, received: %+v", utils.ToJSON(eCfg), utils.ToJSON(cfg))
	}
}

func TestDNSAgentJsonCfg(t *testing.T) {
	eCfg := &DNSAgentJsonCfg{
		Enabled: utils.BoolPointer(false),
		Listeners: &[]*ListenerJsnCfg{
			{
				Network: utils.StringPointer("udp"),
				Address: utils.StringPointer("127.0.0.1:53"),
			},
		},

		SessionSConns:     &[]string{utils.ConcatenatedKey(utils.MetaInternal)},
		StatSConns:        &[]string{},
		ThresholdSConns:   &[]string{},
		Timezone:          utils.StringPointer(""),
		RequestProcessors: &[]*ReqProcessorJsnCfg{},
	}
	dfCgrJSONCfg, err := NewCgrJsonCfgFromBytes([]byte(CGRATES_CFG_JSON))
	if err != nil {
		t.Error(err)
	}
	cfg := new(DNSAgentJsonCfg)
	if err := dfCgrJSONCfg.GetSection(context.Background(), DNSAgentJSON, cfg); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Errorf("expecting: %+v, received: %+v", utils.ToJSON(eCfg), utils.ToJSON(cfg))
	}
}

func TestDfAttributeServJsonCfg(t *testing.T) {
	eCfg := &AttributeSJsonCfg{
		Enabled:                  utils.BoolPointer(false),
		Stats_conns:              &[]string{},
		Resources_conns:          &[]string{},
		Accounts_conns:           &[]string{},
		Indexed_selects:          utils.BoolPointer(true),
		String_indexed_fields:    nil,
		Prefix_indexed_fields:    &[]string{},
		Suffix_indexed_fields:    &[]string{},
		Exists_indexed_fields:    &[]string{},
		Notexists_indexed_fields: &[]string{},
		Nested_fields:            utils.BoolPointer(false),
		Opts:                     &AttributesOptsJson{},
	}
	dfCgrJSONCfg, err := NewCgrJsonCfgFromBytes([]byte(CGRATES_CFG_JSON))
	if err != nil {
		t.Error(err)
	}
	cfg := new(AttributeSJsonCfg)
	if err := dfCgrJSONCfg.GetSection(context.Background(), AttributeSJSON, cfg); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ToJSON(eCfg), utils.ToJSON(cfg))
	}
}

func TestDfChargerServJsonCfg(t *testing.T) {
	eCfg := &ChargerSJsonCfg{
		Enabled:                  utils.BoolPointer(false),
		Indexed_selects:          utils.BoolPointer(true),
		Attributes_conns:         &[]string{},
		String_indexed_fields:    nil,
		Prefix_indexed_fields:    &[]string{},
		Suffix_indexed_fields:    &[]string{},
		Exists_indexed_fields:    &[]string{},
		Notexists_indexed_fields: &[]string{},
		Nested_fields:            utils.BoolPointer(false),
	}
	dfCgrJSONCfg, err := NewCgrJsonCfgFromBytes([]byte(CGRATES_CFG_JSON))
	if err != nil {
		t.Error(err)
	}
	cfg := new(ChargerSJsonCfg)
	if err := dfCgrJSONCfg.GetSection(context.Background(), ChargerSJSON, cfg); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Error("Received: ", utils.ToJSON(cfg))
	}
}

func TestDfFilterSJsonCfg(t *testing.T) {
	eCfg := &FilterSJsonCfg{
		Stats_conns:     &[]string{},
		Resources_conns: &[]string{},
		Accounts_conns:  &[]string{},
		Trends_conns:    &[]string{},
		Rankings_conns:  &[]string{},
	}
	dfCgrJSONCfg, err := NewCgrJsonCfgFromBytes([]byte(CGRATES_CFG_JSON))
	if err != nil {
		t.Error(err)
	}
	cfg := new(FilterSJsonCfg)
	if err := dfCgrJSONCfg.GetSection(context.Background(), FilterSJSON, cfg); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Errorf("Expected: %s, received: %s", utils.ToJSON(eCfg), utils.ToJSON(cfg))
	}
}

func TestDfResourceLimiterSJsonCfg(t *testing.T) {
	eCfg := &ResourceSJsonCfg{
		Enabled:                  utils.BoolPointer(false),
		Indexed_selects:          utils.BoolPointer(true),
		Thresholds_conns:         &[]string{},
		Store_interval:           utils.StringPointer(""),
		String_indexed_fields:    nil,
		Prefix_indexed_fields:    &[]string{},
		Suffix_indexed_fields:    &[]string{},
		Exists_indexed_fields:    &[]string{},
		Notexists_indexed_fields: &[]string{},
		Nested_fields:            utils.BoolPointer(false),
		Opts:                     &ResourcesOptsJson{},
	}
	dfCgrJSONCfg, err := NewCgrJsonCfgFromBytes([]byte(CGRATES_CFG_JSON))
	if err != nil {
		t.Error(err)
	}
	cfg := new(ResourceSJsonCfg)
	if err := dfCgrJSONCfg.GetSection(context.Background(), ResourceSJSON, cfg); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Errorf("Expected: %s, received: %s", utils.ToJSON(eCfg), utils.ToJSON(cfg))
	}
}

func TestDfStatServiceJsonCfg(t *testing.T) {
	eCfg := &StatServJsonCfg{
		Enabled:                  utils.BoolPointer(false),
		Indexed_selects:          utils.BoolPointer(true),
		Store_interval:           utils.StringPointer(""),
		Store_uncompressed_limit: utils.IntPointer(0),
		Thresholds_conns:         &[]string{},
		String_indexed_fields:    nil,
		Prefix_indexed_fields:    &[]string{},
		Suffix_indexed_fields:    &[]string{},
		Exists_indexed_fields:    &[]string{},
		Notexists_indexed_fields: &[]string{},
		Nested_fields:            utils.BoolPointer(false),
		Opts:                     &StatsOptsJson{},
		Ees_conns:                &[]string{},
		Ees_exporter_ids:         &[]string{},
	}
	dfCgrJSONCfg, err := NewCgrJsonCfgFromBytes([]byte(CGRATES_CFG_JSON))
	if err != nil {
		t.Error(err)
	}
	cfg := new(StatServJsonCfg)
	if err := dfCgrJSONCfg.GetSection(context.Background(), StatSJSON, cfg); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Error("Received: ", utils.ToJSON(cfg))
	}
}

func TestDfThresholdSJsonCfg(t *testing.T) {
	eCfg := &ThresholdSJsonCfg{
		Enabled:                  utils.BoolPointer(false),
		Indexed_selects:          utils.BoolPointer(true),
		Store_interval:           utils.StringPointer(""),
		String_indexed_fields:    nil,
		Prefix_indexed_fields:    &[]string{},
		Suffix_indexed_fields:    &[]string{},
		Exists_indexed_fields:    &[]string{},
		Notexists_indexed_fields: &[]string{},
		Nested_fields:            utils.BoolPointer(false),
		Actions_conns:            &[]string{},
		Opts:                     &ThresholdsOptsJson{},
		Ees_conns:                &[]string{},
		Ees_exporter_ids:         &[]string{},
	}
	dfCgrJSONCfg, err := NewCgrJsonCfgFromBytes([]byte(CGRATES_CFG_JSON))
	if err != nil {
		t.Error(err)
	}
	cfg := new(ThresholdSJsonCfg)
	if err := dfCgrJSONCfg.GetSection(context.Background(), ThresholdSJSON, cfg); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Errorf("expecting: %+v, received: %+v", utils.ToJSON(eCfg), utils.ToJSON(cfg))
	}
}

func TestDfRouteSJsonCfg(t *testing.T) {
	eCfg := &RouteSJsonCfg{
		Enabled:                  utils.BoolPointer(false),
		Indexed_selects:          utils.BoolPointer(true),
		String_indexed_fields:    nil,
		Prefix_indexed_fields:    &[]string{},
		Suffix_indexed_fields:    &[]string{},
		Exists_indexed_fields:    &[]string{},
		Notexists_indexed_fields: &[]string{},
		Attributes_conns:         &[]string{},
		Resources_conns:          &[]string{},
		Stats_conns:              &[]string{},
		Rates_conns:              &[]string{},
		Accounts_conns:           &[]string{},
		Default_ratio:            utils.IntPointer(1),
		Nested_fields:            utils.BoolPointer(false),
		Opts:                     &RoutesOptsJson{},
	}
	dfCgrJSONCfg, err := NewCgrJsonCfgFromBytes([]byte(CGRATES_CFG_JSON))
	if err != nil {
		t.Error(err)
	}
	cfg := new(RouteSJsonCfg)
	if err := dfCgrJSONCfg.GetSection(context.Background(), RouteSJSON, cfg); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Errorf("expecting: %+v, received: %+v", utils.ToJSON(eCfg), utils.ToJSON(cfg))
	}
}

func TestDfLoaderJsonCfg(t *testing.T) {
	eCfg := []*LoaderJsonCfg{
		{
			ID:              utils.StringPointer(utils.MetaDefault),
			Enabled:         utils.BoolPointer(false),
			Tenant:          utils.StringPointer(""),
			Run_delay:       utils.StringPointer("0"),
			Lockfile_path:   utils.StringPointer(".cgr.lck"),
			Caches_conns:    &[]string{utils.MetaInternal},
			Field_separator: utils.StringPointer(","),
			Tp_in_dir:       utils.StringPointer("/var/spool/cgrates/loader/in"),
			Tp_out_dir:      utils.StringPointer("/var/spool/cgrates/loader/out"),
			Action:          utils.StringPointer(utils.MetaStore),
			Opts:            &LoaderJsonOptsCfg{WithIndex: utils.BoolPointer(true)},
			Data: &[]*LoaderJsonDataType{
				{
					Type:      utils.StringPointer(utils.MetaFilters),
					File_name: utils.StringPointer(utils.FiltersCsv),
					Fields: &[]*FcTemplateJsonCfg{
						{Tag: utils.StringPointer(utils.Tenant),
							Path:      utils.StringPointer(utils.Tenant),
							Type:      utils.StringPointer(utils.MetaVariable),
							Value:     utils.StringPointer("~*req.0"),
							Mandatory: utils.BoolPointer(true)},
						{Tag: utils.StringPointer(utils.ID),
							Path:      utils.StringPointer(utils.ID),
							Type:      utils.StringPointer(utils.MetaVariable),
							Value:     utils.StringPointer("~*req.1"),
							Mandatory: utils.BoolPointer(true)},
						{Tag: utils.StringPointer("Type"),
							Path:       utils.StringPointer("Rules.Type"),
							Type:       utils.StringPointer(utils.MetaVariable),
							Value:      utils.StringPointer("~*req.2"),
							New_branch: utils.BoolPointer(true)},
						{Tag: utils.StringPointer("Element"),
							Path:  utils.StringPointer("Rules.Element"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.3")},
						{Tag: utils.StringPointer("Values"),
							Path:  utils.StringPointer("Rules.Values"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.4")},
					},
				},
				{
					Type:      utils.StringPointer(utils.MetaAttributes),
					File_name: utils.StringPointer(utils.AttributesCsv),
					Fields: &[]*FcTemplateJsonCfg{
						{Tag: utils.StringPointer("TenantID"),
							Path:      utils.StringPointer(utils.Tenant),
							Type:      utils.StringPointer(utils.MetaVariable),
							Value:     utils.StringPointer("~*req.0"),
							Mandatory: utils.BoolPointer(true)},
						{Tag: utils.StringPointer("ProfileID"),
							Path:      utils.StringPointer(utils.ID),
							Type:      utils.StringPointer(utils.MetaVariable),
							Value:     utils.StringPointer("~*req.1"),
							Mandatory: utils.BoolPointer(true)},
						{Tag: utils.StringPointer("FilterIDs"),
							Path:  utils.StringPointer(utils.FilterIDs),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.2")},
						{Tag: utils.StringPointer("Weights"),
							Path:  utils.StringPointer(utils.Weights),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.3")},
						{Tag: utils.StringPointer("Blockers"),
							Path:  utils.StringPointer("Blockers"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.4")},
						{Tag: utils.StringPointer("AttributeFilterIDs"),
							Path:       utils.StringPointer("Attributes.FilterIDs"),
							Type:       utils.StringPointer(utils.MetaVariable),
							Value:      utils.StringPointer("~*req.5"),
							New_branch: utils.BoolPointer(true)},
						{Tag: utils.StringPointer("AttributeBlockers"),
							Path:  utils.StringPointer("Attributes.Blockers"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.6")},
						{Tag: utils.StringPointer("Path"),
							Path:  utils.StringPointer("Attributes." + utils.Path),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.7")},
						{Tag: utils.StringPointer("Type"),
							Path:  utils.StringPointer("Attributes.Type"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.8")},
						{Tag: utils.StringPointer("Value"),
							Path:  utils.StringPointer("Attributes.Value"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.9")},
					},
				},
				{
					Type:      utils.StringPointer(utils.MetaResources),
					File_name: utils.StringPointer(utils.ResourcesCsv),
					Fields: &[]*FcTemplateJsonCfg{
						{Tag: utils.StringPointer(utils.Tenant),
							Path:      utils.StringPointer(utils.Tenant),
							Type:      utils.StringPointer(utils.MetaVariable),
							Value:     utils.StringPointer("~*req.0"),
							Mandatory: utils.BoolPointer(true)},
						{Tag: utils.StringPointer(utils.ID),
							Path:      utils.StringPointer(utils.ID),
							Type:      utils.StringPointer(utils.MetaVariable),
							Value:     utils.StringPointer("~*req.1"),
							Mandatory: utils.BoolPointer(true)},
						{Tag: utils.StringPointer("FilterIDs"),
							Path:  utils.StringPointer("FilterIDs"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.2")},
						{Tag: utils.StringPointer("Weights"),
							Path:  utils.StringPointer("Weights"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.3")},
						{Tag: utils.StringPointer("TTL"),
							Path:  utils.StringPointer("UsageTTL"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.4")},
						{Tag: utils.StringPointer("Limit"),
							Path:  utils.StringPointer("Limit"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.5")},
						{Tag: utils.StringPointer("AllocationMessage"),
							Path:  utils.StringPointer("AllocationMessage"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.6")},
						{Tag: utils.StringPointer("Blocker"),
							Path:  utils.StringPointer("Blocker"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.7")},
						{Tag: utils.StringPointer("Stored"),
							Path:  utils.StringPointer("Stored"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.8")},
						{Tag: utils.StringPointer("ThresholdIDs"),
							Path:  utils.StringPointer("ThresholdIDs"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.9")},
					},
				},
				{
					Type:      utils.StringPointer(utils.MetaIPs),
					File_name: utils.StringPointer(utils.IPsCsv),
					Fields: &[]*FcTemplateJsonCfg{
						{
							Tag:       utils.StringPointer(utils.Tenant),
							Path:      utils.StringPointer(utils.Tenant),
							Type:      utils.StringPointer(utils.MetaVariable),
							Value:     utils.StringPointer("~*req.0"),
							Mandatory: utils.BoolPointer(true),
						},
						{
							Tag:       utils.StringPointer(utils.ID),
							Path:      utils.StringPointer(utils.ID),
							Type:      utils.StringPointer(utils.MetaVariable),
							Value:     utils.StringPointer("~*req.1"),
							Mandatory: utils.BoolPointer(true),
						},
						{
							Tag:   utils.StringPointer("FilterIDs"),
							Path:  utils.StringPointer("FilterIDs"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.2"),
						},
						{
							Tag:   utils.StringPointer("Weights"),
							Path:  utils.StringPointer("Weights"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.3"),
						},
						{
							Tag:   utils.StringPointer("TTL"),
							Path:  utils.StringPointer("TTL"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.4"),
						},
						{
							Tag:   utils.StringPointer("Stored"),
							Path:  utils.StringPointer("Stored"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.5"),
						},
						{
							Tag:        utils.StringPointer("PoolID"),
							Path:       utils.StringPointer("Pools.ID"),
							Type:       utils.StringPointer(utils.MetaVariable),
							Value:      utils.StringPointer("~*req.6"),
							New_branch: utils.BoolPointer(true),
						},
						{
							Tag:   utils.StringPointer("PoolFilterIDs"),
							Path:  utils.StringPointer("Pools.FilterIDs"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.7"),
						},
						{
							Tag:   utils.StringPointer("PoolType"),
							Path:  utils.StringPointer("Pools.Type"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.8"),
						},
						{
							Tag:   utils.StringPointer("PoolRange"),
							Path:  utils.StringPointer("Pools.Range"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.9"),
						},
						{
							Tag:   utils.StringPointer("PoolStrategy"),
							Path:  utils.StringPointer("Pools.Strategy"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.10"),
						},
						{
							Tag:   utils.StringPointer("PoolMessage"),
							Path:  utils.StringPointer("Pools.Message"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.11"),
						},
						{
							Tag:   utils.StringPointer("PoolWeights"),
							Path:  utils.StringPointer("Pools.Weights"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.12"),
						},
						{
							Tag:   utils.StringPointer("PoolBlockers"),
							Path:  utils.StringPointer("Pools.Blockers"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.13"),
						},
					},
				},
				{
					Type:      utils.StringPointer(utils.MetaStats),
					File_name: utils.StringPointer(utils.StatsCsv),
					Fields: &[]*FcTemplateJsonCfg{
						{Tag: utils.StringPointer(utils.Tenant),
							Path:      utils.StringPointer(utils.Tenant),
							Type:      utils.StringPointer(utils.MetaVariable),
							Value:     utils.StringPointer("~*req.0"),
							Mandatory: utils.BoolPointer(true)},
						{Tag: utils.StringPointer(utils.ID),
							Path:      utils.StringPointer(utils.ID),
							Type:      utils.StringPointer(utils.MetaVariable),
							Value:     utils.StringPointer("~*req.1"),
							Mandatory: utils.BoolPointer(true)},
						{Tag: utils.StringPointer("FilterIDs"),
							Path:  utils.StringPointer("FilterIDs"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.2")},
						{Tag: utils.StringPointer("Weights"),
							Path:  utils.StringPointer("Weights"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.3")},
						{Tag: utils.StringPointer("Blockers"),
							Path:  utils.StringPointer("Blockers"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.4")},
						{Tag: utils.StringPointer("QueueLength"),
							Path:  utils.StringPointer("QueueLength"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.5")},
						{Tag: utils.StringPointer("TTL"),
							Path:  utils.StringPointer("TTL"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.6")},
						{Tag: utils.StringPointer("MinItems"),
							Path:  utils.StringPointer("MinItems"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.7")},
						{Tag: utils.StringPointer("Stored"),
							Path:  utils.StringPointer("Stored"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.8")},
						{Tag: utils.StringPointer("ThresholdIDs"),
							Path:  utils.StringPointer("ThresholdIDs"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.9")},
						{Tag: utils.StringPointer("MetricIDs"),
							Path:       utils.StringPointer("Metrics.MetricID"),
							Type:       utils.StringPointer(utils.MetaVariable),
							Value:      utils.StringPointer("~*req.10"),
							New_branch: utils.BoolPointer(true)},
						{Tag: utils.StringPointer("MetricFilterIDs"),
							Path:  utils.StringPointer("Metrics.FilterIDs"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.11")},
						{Tag: utils.StringPointer("MetricBlockers"),
							Path:  utils.StringPointer("Metrics.Blockers"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.12")},
					},
				},
				{
					Type:      utils.StringPointer(utils.MetaThresholds),
					File_name: utils.StringPointer(utils.ThresholdsCsv),
					Fields: &[]*FcTemplateJsonCfg{
						{Tag: utils.StringPointer(utils.Tenant),
							Path:      utils.StringPointer(utils.Tenant),
							Type:      utils.StringPointer(utils.MetaVariable),
							Value:     utils.StringPointer("~*req.0"),
							Mandatory: utils.BoolPointer(true)},
						{Tag: utils.StringPointer(utils.ID),
							Path:      utils.StringPointer(utils.ID),
							Type:      utils.StringPointer(utils.MetaVariable),
							Value:     utils.StringPointer("~*req.1"),
							Mandatory: utils.BoolPointer(true)},
						{Tag: utils.StringPointer("FilterIDs"),
							Path:  utils.StringPointer("FilterIDs"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.2")},
						{Tag: utils.StringPointer("Weights"),
							Path:  utils.StringPointer("Weights"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.3")},
						{Tag: utils.StringPointer("MaxHits"),
							Path:  utils.StringPointer("MaxHits"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.4")},
						{Tag: utils.StringPointer("MinHits"),
							Path:  utils.StringPointer("MinHits"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.5")},
						{Tag: utils.StringPointer("MinSleep"),
							Path:  utils.StringPointer("MinSleep"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.6")},
						{Tag: utils.StringPointer("Blocker"),
							Path:  utils.StringPointer("Blocker"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.7")},
						{Tag: utils.StringPointer("ActionProfileIDs"),
							Path:  utils.StringPointer("ActionProfileIDs"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.8")},
						{Tag: utils.StringPointer("Async"),
							Path:  utils.StringPointer("Async"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.9")},
						{Tag: utils.StringPointer("EeIDs"),
							Path:  utils.StringPointer("EeIDs"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.10"),
						},
					},
				},
				{
					Type:      utils.StringPointer(utils.MetaTrends),
					File_name: utils.StringPointer(utils.TrendsCsv),
					Fields: &[]*FcTemplateJsonCfg{
						{Tag: utils.StringPointer(utils.Tenant),
							Path:      utils.StringPointer(utils.Tenant),
							Type:      utils.StringPointer(utils.MetaVariable),
							Value:     utils.StringPointer("~*req.0"),
							Mandatory: utils.BoolPointer(true),
						},
						{Tag: utils.StringPointer(utils.ID),
							Path:      utils.StringPointer(utils.ID),
							Type:      utils.StringPointer(utils.MetaVariable),
							Value:     utils.StringPointer("~*req.1"),
							Mandatory: utils.BoolPointer(true),
						},
						{Tag: utils.StringPointer(utils.Schedule),
							Path:  utils.StringPointer(utils.Schedule),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.2"),
						},
						{Tag: utils.StringPointer(utils.StatID),
							Path:  utils.StringPointer(utils.StatID),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.3"),
						},
						{Tag: utils.StringPointer(utils.Metrics),
							Path:  utils.StringPointer(utils.Metrics),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.4"),
						},
						{Tag: utils.StringPointer(utils.TTL),
							Path:  utils.StringPointer(utils.TTL),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.5"),
						},
						{Tag: utils.StringPointer(utils.QueueLength),
							Path:  utils.StringPointer(utils.QueueLength),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.6"),
						},
						{Tag: utils.StringPointer(utils.MinItems),
							Path:  utils.StringPointer(utils.MinItems),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.7"),
						},
						{Tag: utils.StringPointer(utils.CorrelationType),
							Path:  utils.StringPointer(utils.CorrelationType),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.8"),
						},
						{Tag: utils.StringPointer(utils.Tolerance),
							Path:  utils.StringPointer(utils.Tolerance),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.9"),
						},
						{Tag: utils.StringPointer(utils.Stored),
							Path:  utils.StringPointer(utils.Stored),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.10"),
						},
						{Tag: utils.StringPointer(utils.ThresholdIDs),
							Path:  utils.StringPointer(utils.ThresholdIDs),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.11"),
						},
					},
				},
				{Type: utils.StringPointer(utils.MetaRankings),
					File_name: utils.StringPointer(utils.RankingsCsv),
					Fields: &[]*FcTemplateJsonCfg{
						{Tag: utils.StringPointer(utils.Tenant),
							Path:      utils.StringPointer(utils.Tenant),
							Type:      utils.StringPointer(utils.MetaVariable),
							Value:     utils.StringPointer("~*req.0"),
							Mandatory: utils.BoolPointer(true),
						},
						{Tag: utils.StringPointer(utils.ID),
							Path:      utils.StringPointer(utils.ID),
							Type:      utils.StringPointer(utils.MetaVariable),
							Value:     utils.StringPointer("~*req.1"),
							Mandatory: utils.BoolPointer(true),
						},
						{Tag: utils.StringPointer(utils.Schedule),
							Path:  utils.StringPointer(utils.Schedule),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.2"),
						},
						{Tag: utils.StringPointer(utils.StatIDs),
							Path:  utils.StringPointer(utils.StatIDs),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.3"),
						},
						{Tag: utils.StringPointer(utils.MetricIDs),
							Path:  utils.StringPointer(utils.MetricIDs),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.4"),
						},
						{Tag: utils.StringPointer(utils.Sorting),
							Path:  utils.StringPointer(utils.Sorting),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.5"),
						},
						{Tag: utils.StringPointer(utils.SortingParameters),
							Path:  utils.StringPointer(utils.SortingParameters),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.6"),
						},
						{Tag: utils.StringPointer(utils.Stored),
							Path:  utils.StringPointer(utils.Stored),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.7"),
						},
						{Tag: utils.StringPointer(utils.ThresholdIDs),
							Path:  utils.StringPointer(utils.ThresholdIDs),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.8"),
						},
					},
				},
				{
					Type:      utils.StringPointer(utils.MetaRoutes),
					File_name: utils.StringPointer(utils.RoutesCsv),
					Fields: &[]*FcTemplateJsonCfg{
						{Tag: utils.StringPointer(utils.Tenant),
							Path:      utils.StringPointer(utils.Tenant),
							Type:      utils.StringPointer(utils.MetaVariable),
							Value:     utils.StringPointer("~*req.0"),
							Mandatory: utils.BoolPointer(true)},
						{Tag: utils.StringPointer(utils.ID),
							Path:      utils.StringPointer(utils.ID),
							Type:      utils.StringPointer(utils.MetaVariable),
							Value:     utils.StringPointer("~*req.1"),
							Mandatory: utils.BoolPointer(true)},
						{Tag: utils.StringPointer("FilterIDs"),
							Path:  utils.StringPointer("FilterIDs"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.2")},
						{Tag: utils.StringPointer("Weights"),
							Path:  utils.StringPointer("Weights"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.3")},
						{Tag: utils.StringPointer("Blockers"),
							Path:  utils.StringPointer("Blockers"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.4")},
						{Tag: utils.StringPointer("Sorting"),
							Path:  utils.StringPointer("Sorting"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.5")},
						{Tag: utils.StringPointer("SortingParameters"),
							Path:  utils.StringPointer("SortingParameters"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.6")},
						{Tag: utils.StringPointer("RouteID"),
							Path:       utils.StringPointer("Routes.ID"),
							Type:       utils.StringPointer(utils.MetaVariable),
							Value:      utils.StringPointer("~*req.7"),
							New_branch: utils.BoolPointer(true)},
						{Tag: utils.StringPointer("RouteFilterIDs"),
							Path:  utils.StringPointer("Routes.FilterIDs"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.8")},
						{Tag: utils.StringPointer("RouteAccountIDs"),
							Path:  utils.StringPointer("Routes.AccountIDs"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.9")},
						{Tag: utils.StringPointer("RouteRateProfileIDs"),
							Path:  utils.StringPointer("Routes.RateProfileIDs"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.10")},
						{Tag: utils.StringPointer("RouteResourceIDs"),
							Path:  utils.StringPointer("Routes.ResourceIDs"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.11")},
						{Tag: utils.StringPointer("RouteStatIDs"),
							Path:  utils.StringPointer("Routes.StatIDs"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.12")},
						{Tag: utils.StringPointer("RouteWeights"),
							Path:  utils.StringPointer("Routes.Weights"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.13")},
						{Tag: utils.StringPointer("RouteBlockers"),
							Path:  utils.StringPointer("Routes.Blockers"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.14")},
						{Tag: utils.StringPointer("RouteParameters"),
							Path:  utils.StringPointer("Routes.RouteParameters"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.15")},
					},
				},
				{
					Type:      utils.StringPointer(utils.MetaChargers),
					File_name: utils.StringPointer(utils.ChargersCsv),
					Fields: &[]*FcTemplateJsonCfg{
						{Tag: utils.StringPointer(utils.Tenant),
							Path:      utils.StringPointer(utils.Tenant),
							Type:      utils.StringPointer(utils.MetaVariable),
							Value:     utils.StringPointer("~*req.0"),
							Mandatory: utils.BoolPointer(true)},
						{Tag: utils.StringPointer(utils.ID),
							Path:      utils.StringPointer(utils.ID),
							Type:      utils.StringPointer(utils.MetaVariable),
							Value:     utils.StringPointer("~*req.1"),
							Mandatory: utils.BoolPointer(true)},
						{Tag: utils.StringPointer("FilterIDs"),
							Path:  utils.StringPointer("FilterIDs"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.2")},
						{Tag: utils.StringPointer("Weights"),
							Path:  utils.StringPointer("Weights"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.3")},
						{Tag: utils.StringPointer("Blockers"),
							Path:  utils.StringPointer("Blockers"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.4")},
						{Tag: utils.StringPointer("RunID"),
							Path:  utils.StringPointer("RunID"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.5")},
						{Tag: utils.StringPointer("AttributeIDs"),
							Path:  utils.StringPointer("AttributeIDs"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.6")},
					},
				},
				{
					Type:      utils.StringPointer(utils.MetaRateProfiles),
					File_name: utils.StringPointer(utils.RatesCsv),
					Fields: &[]*FcTemplateJsonCfg{
						{Tag: utils.StringPointer(utils.Tenant),
							Path:      utils.StringPointer(utils.Tenant),
							Type:      utils.StringPointer(utils.MetaVariable),
							Value:     utils.StringPointer("~*req.0"),
							Mandatory: utils.BoolPointer(true)},
						{Tag: utils.StringPointer(utils.ID),
							Path:      utils.StringPointer(utils.ID),
							Type:      utils.StringPointer(utils.MetaVariable),
							Value:     utils.StringPointer("~*req.1"),
							Mandatory: utils.BoolPointer(true)},
						{Tag: utils.StringPointer("FilterIDs"),
							Path:  utils.StringPointer("FilterIDs"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.2")},
						{Tag: utils.StringPointer("Weights"),
							Path:  utils.StringPointer("Weights"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.3")},
						{Tag: utils.StringPointer("MinCost"),
							Path:  utils.StringPointer("MinCost"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.4")},
						{Tag: utils.StringPointer("MaxCost"),
							Path:  utils.StringPointer("MaxCost"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.5")},
						{Tag: utils.StringPointer("MaxCostStrategy"),
							Path:  utils.StringPointer("MaxCostStrategy"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.6")},
						{Tag: utils.StringPointer("RateFilterIDs"),
							Path:    utils.StringPointer("Rates[<~*req.7>].FilterIDs"),
							Type:    utils.StringPointer(utils.MetaVariable),
							Filters: &[]string{"*notempty:~*req.7:"},
							Value:   utils.StringPointer("~*req.8")},
						{Tag: utils.StringPointer("RateActivationTimes"),
							Path:    utils.StringPointer("Rates[<~*req.7>].ActivationTimes"),
							Type:    utils.StringPointer(utils.MetaVariable),
							Filters: &[]string{"*notempty:~*req.7:"},
							Value:   utils.StringPointer("~*req.9")},
						{Tag: utils.StringPointer("RateWeights"),
							Path:    utils.StringPointer("Rates[<~*req.7>].Weights"),
							Type:    utils.StringPointer(utils.MetaVariable),
							Filters: &[]string{"*notempty:~*req.7:"},
							Value:   utils.StringPointer("~*req.10")},
						{Tag: utils.StringPointer("RateBlocker"),
							Path:    utils.StringPointer("Rates[<~*req.7>].Blocker"),
							Type:    utils.StringPointer(utils.MetaVariable),
							Filters: &[]string{"*notempty:~*req.7:"},
							Value:   utils.StringPointer("~*req.11")},
						{Tag: utils.StringPointer("RateIntervalStart"),
							Path:       utils.StringPointer("Rates[<~*req.7>].IntervalRates.IntervalStart"),
							Type:       utils.StringPointer(utils.MetaVariable),
							Filters:    &[]string{"*notempty:~*req.7:"},
							Value:      utils.StringPointer("~*req.12"),
							New_branch: utils.BoolPointer(true)},
						{Tag: utils.StringPointer("RateFixedFee"),
							Path:    utils.StringPointer("Rates[<~*req.7>].IntervalRates.FixedFee"),
							Type:    utils.StringPointer(utils.MetaVariable),
							Filters: &[]string{"*notempty:~*req.7:"},
							Value:   utils.StringPointer("~*req.13")},
						{Tag: utils.StringPointer("RateRecurrentFee"),
							Path:    utils.StringPointer("Rates[<~*req.7>].IntervalRates.RecurrentFee"),
							Type:    utils.StringPointer(utils.MetaVariable),
							Filters: &[]string{"*notempty:~*req.7:"},
							Value:   utils.StringPointer("~*req.14")},
						{Tag: utils.StringPointer("RateUnit"),
							Path:    utils.StringPointer("Rates[<~*req.7>].IntervalRates.Unit"),
							Type:    utils.StringPointer(utils.MetaVariable),
							Filters: &[]string{"*notempty:~*req.7:"},
							Value:   utils.StringPointer("~*req.15")},
						{Tag: utils.StringPointer("RateIncrement"),
							Path:    utils.StringPointer("Rates[<~*req.7>].IntervalRates.Increment"),
							Type:    utils.StringPointer(utils.MetaVariable),
							Filters: &[]string{"*notempty:~*req.7:"},
							Value:   utils.StringPointer("~*req.16")},
					},
				},
				{
					Type:      utils.StringPointer(utils.MetaActionProfiles),
					File_name: utils.StringPointer(utils.ActionsCsv),
					Fields: &[]*FcTemplateJsonCfg{
						{Tag: utils.StringPointer(utils.Tenant),
							Path:      utils.StringPointer(utils.Tenant),
							Type:      utils.StringPointer(utils.MetaVariable),
							Value:     utils.StringPointer("~*req.0"),
							Mandatory: utils.BoolPointer(true)},
						{Tag: utils.StringPointer(utils.ID),
							Path:      utils.StringPointer(utils.ID),
							Type:      utils.StringPointer(utils.MetaVariable),
							Value:     utils.StringPointer("~*req.1"),
							Mandatory: utils.BoolPointer(true)},
						{Tag: utils.StringPointer("FilterIDs"),
							Path:  utils.StringPointer("FilterIDs"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.2")},
						{Tag: utils.StringPointer("Weights"),
							Path:  utils.StringPointer("Weights"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.3")},
						{Tag: utils.StringPointer("Blockers"),
							Path:  utils.StringPointer("Blockers"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.4")},
						{Tag: utils.StringPointer("Schedule"),
							Path:  utils.StringPointer("Schedule"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.5")},
						{Tag: utils.StringPointer("TargetIDs"),
							Path:  utils.StringPointer("Targets[<~*req.6>]"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.7")},
						{Tag: utils.StringPointer("ActionFilterIDs"),
							Path:    utils.StringPointer("Actions[<~*req.8>].FilterIDs"),
							Type:    utils.StringPointer(utils.MetaVariable),
							Filters: &[]string{"*notempty:~*req.8:"},
							Value:   utils.StringPointer("~*req.9")},
						{Tag: utils.StringPointer("ActionTTL"),
							Path:    utils.StringPointer("Actions[<~*req.8>].TTL"),
							Type:    utils.StringPointer(utils.MetaVariable),
							Filters: &[]string{"*notempty:~*req.8:"},
							Value:   utils.StringPointer("~*req.10")},
						{Tag: utils.StringPointer("ActionType"),
							Path:    utils.StringPointer("Actions[<~*req.8>].Type"),
							Type:    utils.StringPointer(utils.MetaVariable),
							Filters: &[]string{"*notempty:~*req.8:"},
							Value:   utils.StringPointer("~*req.11")},
						{Tag: utils.StringPointer("ActionOpts"),
							Path:    utils.StringPointer("Actions[<~*req.8>].Opts"),
							Type:    utils.StringPointer(utils.MetaVariable),
							Filters: &[]string{"*notempty:~*req.8:"},
							Value:   utils.StringPointer("~*req.12")},
						{Tag: utils.StringPointer("ActionWeights"),
							Path:    utils.StringPointer("Actions[<~*req.8>].Weights"),
							Type:    utils.StringPointer(utils.MetaVariable),
							Filters: &[]string{"*notempty:~*req.8:"},
							Value:   utils.StringPointer("~*req.13")},
						{Tag: utils.StringPointer("ActionBlockers"),
							Path:    utils.StringPointer("Actions[<~*req.8>].Blockers"),
							Type:    utils.StringPointer(utils.MetaVariable),
							Filters: &[]string{"*notempty:~*req.8:"},
							Value:   utils.StringPointer("~*req.14")},
						{Tag: utils.StringPointer("ActionDiktatsID"),
							Path:       utils.StringPointer("Actions[<~*req.8>].Diktats.ID"),
							Type:       utils.StringPointer(utils.MetaVariable),
							Filters:    &[]string{"*notempty:~*req.8:"},
							Value:      utils.StringPointer("~*req.15"),
							New_branch: utils.BoolPointer(true)},
						{Tag: utils.StringPointer("ActionDiktatsFilterIDs"),
							Path:    utils.StringPointer("Actions[<~*req.8>].Diktats.FilterIDs"),
							Type:    utils.StringPointer(utils.MetaVariable),
							Filters: &[]string{"*notempty:~*req.8:"},
							Value:   utils.StringPointer("~*req.16")},
						{Tag: utils.StringPointer("ActionDiktatsOpts"),
							Path:    utils.StringPointer("Actions[<~*req.8>].Diktats.Opts"),
							Type:    utils.StringPointer(utils.MetaVariable),
							Filters: &[]string{"*notempty:~*req.8:"},
							Value:   utils.StringPointer("~*req.17")},
						{Tag: utils.StringPointer("ActionDiktatsWeights"),
							Path:    utils.StringPointer("Actions[<~*req.8>].Diktats.Weights"),
							Type:    utils.StringPointer(utils.MetaVariable),
							Filters: &[]string{"*notempty:~*req.8:"},
							Value:   utils.StringPointer("~*req.18")},
						{Tag: utils.StringPointer("ActionDiktatsBlockers"),
							Path:    utils.StringPointer("Actions[<~*req.8>].Diktats.Blockers"),
							Type:    utils.StringPointer(utils.MetaVariable),
							Filters: &[]string{"*notempty:~*req.8:"},
							Value:   utils.StringPointer("~*req.19")},
					},
				},
				{
					Type:      utils.StringPointer(utils.MetaAccounts),
					File_name: utils.StringPointer(utils.AccountsCsv),
					Fields: &[]*FcTemplateJsonCfg{
						{Tag: utils.StringPointer(utils.Tenant),
							Path:      utils.StringPointer(utils.Tenant),
							Type:      utils.StringPointer(utils.MetaVariable),
							Value:     utils.StringPointer("~*req.0"),
							Mandatory: utils.BoolPointer(true)},
						{Tag: utils.StringPointer(utils.ID),
							Path:      utils.StringPointer(utils.ID),
							Type:      utils.StringPointer(utils.MetaVariable),
							Value:     utils.StringPointer("~*req.1"),
							Mandatory: utils.BoolPointer(true)},
						{Tag: utils.StringPointer("FilterIDs"),
							Path:  utils.StringPointer("FilterIDs"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.2")},
						{Tag: utils.StringPointer("Weights"),
							Path:  utils.StringPointer("Weights"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.3")},
						{Tag: utils.StringPointer("Blockers"),
							Path:  utils.StringPointer("Blockers"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.4")},
						{Tag: utils.StringPointer("Opts"),
							Path:  utils.StringPointer("Opts"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.5")},
						{Tag: utils.StringPointer("BalanceFilterIDs"),
							Path:    utils.StringPointer("Balances[<~*req.6>].FilterIDs"),
							Type:    utils.StringPointer(utils.MetaVariable),
							Filters: &[]string{"*notempty:~*req.6:"},
							Value:   utils.StringPointer("~*req.7")},
						{Tag: utils.StringPointer("BalanceWeights"),
							Path:    utils.StringPointer("Balances[<~*req.6>].Weights"),
							Type:    utils.StringPointer(utils.MetaVariable),
							Filters: &[]string{"*notempty:~*req.6:"},
							Value:   utils.StringPointer("~*req.8")},
						{Tag: utils.StringPointer("BalanceBlockers"),
							Path:    utils.StringPointer("Balances[<~*req.6>].Blockers"),
							Type:    utils.StringPointer(utils.MetaVariable),
							Filters: &[]string{"*notempty:~*req.6:"},
							Value:   utils.StringPointer("~*req.9")},
						{Tag: utils.StringPointer("BalanceType"),
							Path:    utils.StringPointer("Balances[<~*req.6>].Type"),
							Type:    utils.StringPointer(utils.MetaVariable),
							Filters: &[]string{"*notempty:~*req.6:"},
							Value:   utils.StringPointer("~*req.10")},
						{Tag: utils.StringPointer("BalanceUnits"),
							Path:    utils.StringPointer("Balances[<~*req.6>].Units"),
							Type:    utils.StringPointer(utils.MetaVariable),
							Filters: &[]string{"*notempty:~*req.6:"},
							Value:   utils.StringPointer("~*req.11")},
						{Tag: utils.StringPointer("BalanceUnitFactors"),
							Path:    utils.StringPointer("Balances[<~*req.6>].UnitFactors"),
							Type:    utils.StringPointer(utils.MetaVariable),
							Filters: &[]string{"*notempty:~*req.6:"},
							Value:   utils.StringPointer("~*req.12")},
						{Tag: utils.StringPointer("BalanceOpts"),
							Path:    utils.StringPointer("Balances[<~*req.6>].Opts"),
							Type:    utils.StringPointer(utils.MetaVariable),
							Filters: &[]string{"*notempty:~*req.6:"},
							Value:   utils.StringPointer("~*req.13")},
						{Tag: utils.StringPointer("BalanceCostIncrements"),
							Path:    utils.StringPointer("Balances[<~*req.6>].CostIncrements"),
							Type:    utils.StringPointer(utils.MetaVariable),
							Filters: &[]string{"*notempty:~*req.6:"},
							Value:   utils.StringPointer("~*req.14")},
						{Tag: utils.StringPointer("BalanceAttributeIDs"),
							Path:    utils.StringPointer("Balances[<~*req.6>].AttributeIDs"),
							Type:    utils.StringPointer(utils.MetaVariable),
							Filters: &[]string{"*notempty:~*req.6:"},
							Value:   utils.StringPointer("~*req.15")},
						{Tag: utils.StringPointer("BalanceRateProfileIDs"),
							Path:    utils.StringPointer("Balances[<~*req.6>].RateProfileIDs"),
							Type:    utils.StringPointer(utils.MetaVariable),
							Filters: &[]string{"*notempty:~*req.6:"},
							Value:   utils.StringPointer("~*req.16")},
						{Tag: utils.StringPointer("ThresholdIDs"),
							Path:  utils.StringPointer("ThresholdIDs"),
							Type:  utils.StringPointer(utils.MetaVariable),
							Value: utils.StringPointer("~*req.17")},
					},
				},
			},
			Cache: map[string]*CacheParamJsonCfg{
				utils.MetaFilters:        {Limit: utils.IntPointer(-1), Ttl: utils.StringPointer("5s"), Static_ttl: utils.BoolPointer(false)},
				utils.MetaAttributes:     {Limit: utils.IntPointer(-1), Ttl: utils.StringPointer("5s"), Static_ttl: utils.BoolPointer(false)},
				utils.MetaResources:      {Limit: utils.IntPointer(-1), Ttl: utils.StringPointer("5s"), Static_ttl: utils.BoolPointer(false)},
				utils.MetaIPs:            {Limit: utils.IntPointer(-1), Ttl: utils.StringPointer("5s"), Static_ttl: utils.BoolPointer(false)},
				utils.MetaStats:          {Limit: utils.IntPointer(-1), Ttl: utils.StringPointer("5s"), Static_ttl: utils.BoolPointer(false)},
				utils.MetaThresholds:     {Limit: utils.IntPointer(-1), Ttl: utils.StringPointer("5s"), Static_ttl: utils.BoolPointer(false)},
				utils.MetaRoutes:         {Limit: utils.IntPointer(-1), Ttl: utils.StringPointer("5s"), Static_ttl: utils.BoolPointer(false)},
				utils.MetaChargers:       {Limit: utils.IntPointer(-1), Ttl: utils.StringPointer("5s"), Static_ttl: utils.BoolPointer(false)},
				utils.MetaRateProfiles:   {Limit: utils.IntPointer(-1), Ttl: utils.StringPointer("5s"), Static_ttl: utils.BoolPointer(false)},
				utils.MetaActionProfiles: {Limit: utils.IntPointer(-1), Ttl: utils.StringPointer("5s"), Static_ttl: utils.BoolPointer(false)},
				utils.MetaAccounts:       {Limit: utils.IntPointer(-1), Ttl: utils.StringPointer("5s"), Static_ttl: utils.BoolPointer(false)},
				utils.MetaTrends:         {Limit: utils.IntPointer(-1), Ttl: utils.StringPointer("5s"), Static_ttl: utils.BoolPointer(false)},
				utils.MetaRankings:       {Limit: utils.IntPointer(-1), Ttl: utils.StringPointer("5s"), Static_ttl: utils.BoolPointer(false)},
			},
		},
	}
	dfCgrJSONCfg, err := NewCgrJsonCfgFromBytes([]byte(CGRATES_CFG_JSON))
	if err != nil {
		t.Error(err)
	}
	cfg := new([]*LoaderJsonCfg)
	if err := dfCgrJSONCfg.GetSection(context.Background(), LoaderSJSON, cfg); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, *cfg) {
		t.Errorf("Expecting: %s,\nreceived: %s ",
			utils.ToJSON(eCfg), utils.ToJSON(cfg))
	}
}

func TestDfSureTaxJsonCfg(t *testing.T) {
	eCfg := &SureTaxJsonCfg{
		Url:                     utils.StringPointer(""),
		Client_number:           utils.StringPointer(""),
		Validation_key:          utils.StringPointer(""),
		Business_unit:           utils.StringPointer(""),
		Timezone:                utils.StringPointer("Local"),
		Include_local_cost:      utils.BoolPointer(false),
		Return_file_code:        utils.StringPointer("0"),
		Response_group:          utils.StringPointer("03"),
		Response_type:           utils.StringPointer("D4"),
		Regulatory_code:         utils.StringPointer("03"),
		Client_tracking:         utils.StringPointer(utils.DynamicDataPrefix + utils.MetaOpts + utils.NestingSep + utils.MetaOriginID),
		Customer_number:         utils.StringPointer("~*req.Subject"),
		Orig_number:             utils.StringPointer("~*req.Subject"),
		Term_number:             utils.StringPointer("~*req.Destination"),
		Bill_to_number:          utils.StringPointer(""),
		Zipcode:                 utils.StringPointer(""),
		Plus4:                   utils.StringPointer(""),
		P2PZipcode:              utils.StringPointer(""),
		P2PPlus4:                utils.StringPointer(""),
		Units:                   utils.StringPointer("1"),
		Unit_type:               utils.StringPointer("00"),
		Tax_included:            utils.StringPointer("0"),
		Tax_situs_rule:          utils.StringPointer("04"),
		Trans_type_code:         utils.StringPointer("010101"),
		Sales_type_code:         utils.StringPointer("R"),
		Tax_exemption_code_list: utils.StringPointer(""),
	}
	dfCgrJSONCfg, err := NewCgrJsonCfgFromBytes([]byte(CGRATES_CFG_JSON))
	if err != nil {
		t.Error(err)
	}
	cfg := new(SureTaxJsonCfg)
	if err := dfCgrJSONCfg.GetSection(context.Background(), SureTaxJSON, cfg); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Error("Received: ", cfg)
	}
}

func TestDfHttpJsonCfg(t *testing.T) {
	eCfg := &HTTPJsonCfg{
		JSONRPCURL:        utils.StringPointer("/jsonrpc"),
		RegistrarsURL:     utils.StringPointer("/registrar"),
		WSURL:             utils.StringPointer("/ws"),
		FreeswitchCDRsURL: utils.StringPointer("/freeswitch_json"),
		HTTPCDRs:          utils.StringPointer("/cdr_http"),
		PprofPath:         utils.StringPointer("/debug/pprof/"),
		UseBasicAuth:      utils.BoolPointer(false),
		AuthUsers:         utils.MapStringStringPointer(map[string]string{}),
		ClientOpts: &HTTPClientOptsJson{
			SkipTLSVerification:   utils.BoolPointer(false),
			TLSHandshakeTimeout:   utils.StringPointer("10s"),
			DisableKeepAlives:     utils.BoolPointer(false),
			DisableCompression:    utils.BoolPointer(false),
			MaxIdleConns:          utils.IntPointer(100),
			MaxIdleConnsPerHost:   utils.IntPointer(2),
			MaxConnsPerHost:       utils.IntPointer(0),
			IdleConnTimeout:       utils.StringPointer("90s"),
			ResponseHeaderTimeout: utils.StringPointer("0"),
			ExpectContinueTimeout: utils.StringPointer("0"),
			ForceAttemptHTTP2:     utils.BoolPointer(true),
			DialTimeout:           utils.StringPointer("30s"),
			DialFallbackDelay:     utils.StringPointer("300ms"),
			DialKeepAlive:         utils.StringPointer("30s"),
		},
	}
	dfCgrJSONCfg, err := NewCgrJsonCfgFromBytes([]byte(CGRATES_CFG_JSON))
	if err != nil {
		t.Error(err)
	}
	cfg := new(HTTPJsonCfg)
	if err := dfCgrJSONCfg.GetSection(context.Background(), HTTPJSON, cfg); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Errorf("Expected: %s ,received: %s", utils.ToJSON(eCfg), utils.ToJSON(cfg))
	}
}

func TestDfLoaderCfg(t *testing.T) {
	cred := json.RawMessage(`".gapi/credentials.json"`)
	tok := json.RawMessage(`".gapi/token.json"`)
	eCfg := &LoaderCfgJson{
		Tpid:             utils.StringPointer(""),
		Data_path:        utils.StringPointer("./"),
		Disable_reverse:  utils.BoolPointer(false),
		Field_separator:  utils.StringPointer(","),
		Caches_conns:     &[]string{utils.MetaLocalHost},
		Actions_conns:    &[]string{utils.MetaLocalHost},
		Gapi_credentials: &cred,
		Gapi_token:       &tok,
	}
	dfCgrJSONCfg, err := NewCgrJsonCfgFromBytes([]byte(CGRATES_CFG_JSON))
	if err != nil {
		t.Error(err)
	}
	cfg := new(LoaderCfgJson)
	if err := dfCgrJSONCfg.GetSection(context.Background(), LoaderJSON, cfg); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Errorf("Expected: %s, received: %+v", utils.ToJSON(*eCfg), utils.ToJSON(cfg))
	}
}

func TestDfMigratorCfg(t *testing.T) {
	eCfg := &MigratorCfgJson{
		FromItems: map[string]*FromItemJson{
			utils.MetaAccounts: {
				DbConn: utils.StringPointer(utils.MetaDefault),
			},
			utils.MetaStatQueueProfiles: {
				DbConn: utils.StringPointer(utils.MetaDefault),
			},
			utils.MetaFilters: {
				DbConn: utils.StringPointer(utils.MetaDefault),
			},
			utils.MetaChargerProfiles: {
				DbConn: utils.StringPointer(utils.MetaDefault),
			},
			utils.MetaLoadIDs: {
				DbConn: utils.StringPointer(utils.MetaDefault),
			},
			utils.CacheVersions: {
				DbConn: utils.StringPointer(utils.MetaDefault),
			},
		},
		Users_filters: &[]string{},
		Out_db_opts: &DBOptsJson{
			RedisMaxConns:           utils.IntPointer(10),
			RedisConnectAttempts:    utils.IntPointer(20),
			RedisClusterSync:        utils.StringPointer("5s"),
			RedisClusterOndownDelay: utils.StringPointer("0"),
			RedisConnectTimeout:     utils.StringPointer("0"),
			RedisReadTimeout:        utils.StringPointer("0"),
			RedisWriteTimeout:       utils.StringPointer("0"),
			RedisCACertificate:      utils.StringPointer(utils.EmptyString),
			RedisClientCertificate:  utils.StringPointer(utils.EmptyString),
			RedisClientKey:          utils.StringPointer(utils.EmptyString),
			RedisCluster:            utils.BoolPointer(false),
			RedisSentinel:           utils.StringPointer(utils.EmptyString),
			RedisPoolPipelineWindow: utils.StringPointer("150µs"),
			RedisPoolPipelineLimit:  utils.IntPointer(0),
			RedisTLS:                utils.BoolPointer(false),
			MongoQueryTimeout:       utils.StringPointer("10s"),
			MongoConnScheme:         utils.StringPointer("mongodb"),
		},
	}
	dfCgrJSONCfg, err := NewCgrJsonCfgFromBytes([]byte(CGRATES_CFG_JSON))
	if err != nil {
		t.Error(err)
	}
	cfg := new(MigratorCfgJson)
	if err := dfCgrJSONCfg.GetSection(context.Background(), MigratorJSON, cfg); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Errorf("Expected: %+v, received: %+v", utils.ToJSON(eCfg), utils.ToJSON(cfg))
	}
}

func TestDfTlsCfg(t *testing.T) {
	eCfg := &TlsJsonCfg{
		Server_certificate: utils.StringPointer(""),
		Server_key:         utils.StringPointer(""),
		Ca_certificate:     utils.StringPointer(""),
		Client_certificate: utils.StringPointer(""),
		Client_key:         utils.StringPointer(""),
		Server_name:        utils.StringPointer(""),
		Server_policy:      utils.IntPointer(4),
	}
	dfCgrJSONCfg, err := NewCgrJsonCfgFromBytes([]byte(CGRATES_CFG_JSON))
	if err != nil {
		t.Error(err)
	}
	cfg := new(TlsJsonCfg)
	if err := dfCgrJSONCfg.GetSection(context.Background(), TlsJSON, cfg); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Errorf("Expected: %+v, received: %+v", utils.ToJSON(eCfg), utils.ToJSON(cfg))
	}
}

func TestDfAnalyzerCfg(t *testing.T) {
	eCfg := &AnalyzerSJsonCfg{
		Enabled:          utils.BoolPointer(false),
		Cleanup_interval: utils.StringPointer("1h"),
		Db_path:          utils.StringPointer("/var/spool/cgrates/analyzers"),
		Index_type:       utils.StringPointer(utils.MetaScorch),
		Ees_conns:        &[]string{},
		Ttl:              utils.StringPointer("24h"),
		Opts:             &AnalyzerSOptsJson{},
	}
	dfCgrJSONCfg, err := NewCgrJsonCfgFromBytes([]byte(CGRATES_CFG_JSON))
	if err != nil {
		t.Error(err)
	}
	cfg := new(AnalyzerSJsonCfg)
	if err := dfCgrJSONCfg.GetSection(context.Background(), AnalyzerSJSON, cfg); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Errorf("Expected: %+v, received: %+v", utils.ToJSON(eCfg), utils.ToJSON(cfg))
	}
}

func TestDfApierCfg(t *testing.T) {
	eCfg := &AdminSJsonCfg{
		Enabled:          utils.BoolPointer(false),
		Caches_conns:     &[]string{utils.MetaInternal},
		Actions_conns:    &[]string{},
		Attributes_conns: &[]string{},
		Ees_conns:        &[]string{},
	}
	dfCgrJSONCfg, err := NewCgrJsonCfgFromBytes([]byte(CGRATES_CFG_JSON))
	if err != nil {
		t.Error(err)
	}
	cfg := new(AdminSJsonCfg)
	if err := dfCgrJSONCfg.GetSection(context.Background(), AdminSJSON, cfg); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Errorf("Expected: %+v, received: %+v", utils.ToJSON(eCfg), utils.ToJSON(cfg))
	}
}

func TestDfEventReaderCfg(t *testing.T) {
	cdrFields := []*FcTemplateJsonCfg{
		{Tag: utils.StringPointer(utils.ToR), Path: utils.StringPointer(utils.MetaCgreq + utils.NestingSep + utils.ToR), Type: utils.StringPointer(utils.MetaVariable),
			Value: utils.StringPointer("~*req.2"), Mandatory: utils.BoolPointer(true)},
		{Tag: utils.StringPointer(utils.OriginID), Path: utils.StringPointer(utils.MetaCgreq + utils.NestingSep + utils.OriginID), Type: utils.StringPointer(utils.MetaVariable),
			Value: utils.StringPointer("~*req.3"), Mandatory: utils.BoolPointer(true)},
		{Tag: utils.StringPointer(utils.RequestType), Path: utils.StringPointer(utils.MetaCgreq + utils.NestingSep + utils.RequestType), Type: utils.StringPointer(utils.MetaVariable),
			Value: utils.StringPointer("~*req.4"), Mandatory: utils.BoolPointer(true)},
		{Tag: utils.StringPointer(utils.Tenant), Path: utils.StringPointer(utils.MetaCgreq + utils.NestingSep + utils.Tenant), Type: utils.StringPointer(utils.MetaVariable),
			Value: utils.StringPointer("~*req.6"), Mandatory: utils.BoolPointer(true)},
		{Tag: utils.StringPointer(utils.Category), Path: utils.StringPointer(utils.MetaCgreq + utils.NestingSep + utils.Category), Type: utils.StringPointer(utils.MetaVariable),
			Value: utils.StringPointer("~*req.7"), Mandatory: utils.BoolPointer(true)},
		{Tag: utils.StringPointer(utils.AccountField), Path: utils.StringPointer(utils.MetaCgreq + utils.NestingSep + utils.AccountField), Type: utils.StringPointer(utils.MetaVariable),
			Value: utils.StringPointer("~*req.8"), Mandatory: utils.BoolPointer(true)},
		{Tag: utils.StringPointer(utils.Subject), Path: utils.StringPointer(utils.MetaCgreq + utils.NestingSep + utils.Subject), Type: utils.StringPointer(utils.MetaVariable),
			Value: utils.StringPointer("~*req.9"), Mandatory: utils.BoolPointer(true)},
		{Tag: utils.StringPointer(utils.Destination), Path: utils.StringPointer(utils.MetaCgreq + utils.NestingSep + utils.Destination), Type: utils.StringPointer(utils.MetaVariable),
			Value: utils.StringPointer("~*req.10"), Mandatory: utils.BoolPointer(true)},
		{Tag: utils.StringPointer(utils.SetupTime), Path: utils.StringPointer(utils.MetaCgreq + utils.NestingSep + utils.SetupTime), Type: utils.StringPointer(utils.MetaVariable),
			Value: utils.StringPointer("~*req.11"), Mandatory: utils.BoolPointer(true)},
		{Tag: utils.StringPointer(utils.AnswerTime), Path: utils.StringPointer(utils.MetaCgreq + utils.NestingSep + utils.AnswerTime), Type: utils.StringPointer(utils.MetaVariable),
			Value: utils.StringPointer("~*req.12"), Mandatory: utils.BoolPointer(true)},
		{Tag: utils.StringPointer(utils.Usage), Path: utils.StringPointer(utils.MetaCgreq + utils.NestingSep + utils.Usage), Type: utils.StringPointer(utils.MetaVariable),
			Value: utils.StringPointer("~*req.13"), Mandatory: utils.BoolPointer(true)},
	}
	eCfg := &ERsJsonCfg{
		Enabled:         utils.BoolPointer(false),
		SessionSConns:   &[]string{utils.MetaInternal},
		EEsConns:        &[]string{},
		StatSConns:      &[]string{},
		ThresholdSConns: &[]string{},
		Readers: &[]*EventReaderJsonCfg{
			{
				ID:                   utils.StringPointer(utils.MetaDefault),
				Type:                 utils.StringPointer(utils.MetaNone),
				RunDelay:             utils.StringPointer("0"),
				StartDelay:           utils.StringPointer("0"),
				ConcurrentRequests:   utils.IntPointer(1024),
				SourcePath:           utils.StringPointer("/var/spool/cgrates/ers/in"),
				ProcessedPath:        utils.StringPointer("/var/spool/cgrates/ers/out"),
				Tenant:               utils.StringPointer(utils.EmptyString),
				Timezone:             utils.StringPointer(utils.EmptyString),
				EEsIds:               &[]string{},
				EEsSuccessIDs:        &[]string{},
				EEsFailedIDs:         &[]string{},
				Filters:              &[]string{},
				Flags:                &[]string{},
				Fields:               &cdrFields,
				Reconnects:           utils.IntPointer(-1),
				MaxReconnectInterval: utils.StringPointer("5m"),
				CacheDumpFields:      &[]*FcTemplateJsonCfg{},
				PartialCommitFields:  &[]*FcTemplateJsonCfg{},
				Opts: &EventReaderOptsJson{
					CSVFieldSeparator:   utils.StringPointer(","),
					CSVHeaderDefineChar: utils.StringPointer(":"),
					CSVRowLength:        utils.IntPointer(0),
					PartialCacheAction:  utils.StringPointer(utils.MetaNone),
					PartialOrderField:   utils.StringPointer("~*req.AnswerTime"),
					NATSSubject:         utils.StringPointer("cgrates_cdrs"),
				},
			},
		},
		PartialCacheTTL: utils.StringPointer("1s"),
	}
	dfCgrJSONCfg, err := NewCgrJsonCfgFromBytes([]byte(CGRATES_CFG_JSON))
	if err != nil {
		t.Error(err)
	}
	cfg := new(ERsJsonCfg)
	if err := dfCgrJSONCfg.GetSection(context.Background(), ERsJSON, cfg); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Errorf("Expected: %+v, \nreceived: %+v", utils.ToJSON(eCfg), utils.ToJSON(cfg))
	}
}

func TestDfEventExporterCfg(t *testing.T) {
	eCfg := &EEsJsonCfg{
		Enabled:          utils.BoolPointer(false),
		Attributes_conns: &[]string{},
		Cache: map[string]*CacheParamJsonCfg{
			utils.MetaFileCSV: {
				Limit:      utils.IntPointer(-1),
				Ttl:        utils.StringPointer("5s"),
				Static_ttl: utils.BoolPointer(false),
			},
		},
		Exporters: &[]*EventExporterJsonCfg{
			{
				ID:                   utils.StringPointer(utils.MetaDefault),
				Type:                 utils.StringPointer(utils.MetaNone),
				ExportPath:           utils.StringPointer("/var/spool/cgrates/ees"),
				AttributeContext:     utils.StringPointer(utils.EmptyString),
				Timezone:             utils.StringPointer(utils.EmptyString),
				Filters:              &[]string{},
				AttributeIDs:         &[]string{},
				Flags:                &[]string{},
				Synchronous:          utils.BoolPointer(false),
				Blocker:              utils.BoolPointer(false),
				Attempts:             utils.IntPointer(1),
				Fields:               &[]*FcTemplateJsonCfg{},
				Opts:                 &EventExporterOptsJson{},
				ConcurrentRequests:   utils.IntPointer(0),
				MetricsResetSchedule: utils.StringPointer(""),
				FailedPostsDir:       utils.StringPointer("/var/spool/cgrates/failed_posts"),
				EFsConns:             &[]string{utils.MetaInternal},
			},
		},
	}
	dfCgrJSONCfg, err := NewCgrJsonCfgFromBytes([]byte(CGRATES_CFG_JSON))
	if err != nil {
		t.Error(err)
	}
	cfg := new(EEsJsonCfg)
	if err := dfCgrJSONCfg.GetSection(context.Background(), EEsJSON, cfg); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Errorf("Expected: %+v, \nreceived: %+v", utils.ToJSON(eCfg), utils.ToJSON(cfg))
	}
}

func TestDfRateSJsonCfg(t *testing.T) {
	eCfg := &RateSJsonCfg{
		Enabled:                       utils.BoolPointer(false),
		Indexed_selects:               utils.BoolPointer(true),
		String_indexed_fields:         nil,
		Prefix_indexed_fields:         &[]string{},
		Suffix_indexed_fields:         &[]string{},
		Exists_indexed_fields:         &[]string{},
		Notexists_indexed_fields:      &[]string{},
		Nested_fields:                 utils.BoolPointer(false),
		Rate_indexed_selects:          utils.BoolPointer(true),
		Rate_string_indexed_fields:    nil,
		Rate_prefix_indexed_fields:    &[]string{},
		Rate_suffix_indexed_fields:    &[]string{},
		Rate_exists_indexed_fields:    &[]string{},
		Rate_notexists_indexed_fields: &[]string{},
		Rate_nested_fields:            utils.BoolPointer(false),
		Verbosity:                     utils.IntPointer(1000),
		Opts:                          &RatesOptsJson{},
	}
	dfCgrJSONCfg, err := NewCgrJsonCfgFromBytes([]byte(CGRATES_CFG_JSON))
	if err != nil {
		t.Error(err)
	}
	cfg := new(RateSJsonCfg)
	if err := dfCgrJSONCfg.GetSection(context.Background(), RateSJSON, cfg); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Error("Received: ", utils.ToJSON(cfg))
	}
}

func TestDfTemplateSJsonCfg(t *testing.T) {
	eCfg := FcTemplatesJsonCfg{
		"*fsa": {
			{
				Tag:   utils.StringPointer("ToR"),
				Path:  utils.StringPointer("*cgreq.ToR"),
				Type:  utils.StringPointer(utils.MetaConstant),
				Value: utils.StringPointer(utils.MetaVoice)},
			{
				Tag:   utils.StringPointer("PDD"),
				Path:  utils.StringPointer("*cgreq.PDD"),
				Type:  utils.StringPointer(utils.MetaComposed),
				Value: utils.StringPointer("~*req.variable_progress_mediamsec;ms")},
			{
				Tag:   utils.StringPointer("ACD"),
				Path:  utils.StringPointer("*cgreq.ACD"),
				Type:  utils.StringPointer(utils.MetaComposed),
				Value: utils.StringPointer("~*req.variable_cdr_acd;s")},
			{
				Tag:   utils.StringPointer("OriginID"),
				Path:  utils.StringPointer("*cgreq.OriginID"),
				Type:  utils.StringPointer(utils.MetaVariable),
				Value: utils.StringPointer("~*req.Unique-ID")},
			{
				Tag:   utils.StringPointer("*originID"),
				Path:  utils.StringPointer("*opts.*originID"),
				Type:  utils.StringPointer(utils.MetaVariable),
				Value: utils.StringPointer("~*req.Unique-ID")},
			{
				Tag:   utils.StringPointer("OriginHost"),
				Path:  utils.StringPointer("*cgreq.OriginHost"),
				Type:  utils.StringPointer(utils.MetaVariable),
				Value: utils.StringPointer("~*req.variable_cgr_originhost")},
			{
				Tag:   utils.StringPointer("Account"),
				Path:  utils.StringPointer("*cgreq.Account"),
				Type:  utils.StringPointer(utils.MetaVariable),
				Value: utils.StringPointer("~*req.Caller-Username")},
			{
				Tag:   utils.StringPointer("Source"),
				Path:  utils.StringPointer("*cgreq.Source"),
				Type:  utils.StringPointer(utils.MetaComposed),
				Value: utils.StringPointer("FS_;~*req.Event-Name")},
			{
				Tag:     utils.StringPointer("RequestType"),
				Path:    utils.StringPointer("*cgreq.RequestType"),
				Type:    utils.StringPointer(utils.MetaConstant),
				Filters: &[]string{"*string:*req.variable_process_cdr:false"},
				Value:   utils.StringPointer("*none")},
			{
				Tag:     utils.StringPointer("RequestType"),
				Path:    utils.StringPointer("*cgreq.RequestType"),
				Type:    utils.StringPointer(utils.MetaConstant),
				Filters: &[]string{"*string:*req.Caller-Dialplan:inline"},
				Value:   utils.StringPointer("*none")},
			{
				Tag:     utils.StringPointer("RequestType"),
				Path:    utils.StringPointer("*cgreq.RequestType"),
				Type:    utils.StringPointer(utils.MetaConstant),
				Filters: &[]string{"*exists:*cgreq.RequestType:"},
				Value:   utils.StringPointer("*prepaid")},
			{
				Tag:   utils.StringPointer("Tenant"),
				Path:  utils.StringPointer("*cgreq.Tenant"),
				Type:  utils.StringPointer(utils.MetaConstant),
				Value: utils.StringPointer("cgrates.org")},
			{
				Tag:   utils.StringPointer("Category"),
				Path:  utils.StringPointer("*cgreq.Category"),
				Type:  utils.StringPointer(utils.MetaConstant),
				Value: utils.StringPointer("call")},
			{
				Tag:   utils.StringPointer("Subject"),
				Path:  utils.StringPointer("*cgreq.Subject"),
				Type:  utils.StringPointer(utils.MetaVariable),
				Value: utils.StringPointer("~*req.Caller-Username")},
			{
				Tag:   utils.StringPointer("Destination"),
				Path:  utils.StringPointer("*cgreq.Destination"),
				Type:  utils.StringPointer(utils.MetaVariable),
				Value: utils.StringPointer("~*req.Caller-Destination-Number")},
			{
				Tag:   utils.StringPointer("SetupTime"),
				Path:  utils.StringPointer("*cgreq.SetupTime"),
				Type:  utils.StringPointer(utils.MetaVariable),
				Value: utils.StringPointer("~*req.Caller-Channel-Created-Time")},
			{
				Tag:   utils.StringPointer("AnswerTime"),
				Path:  utils.StringPointer("*cgreq.AnswerTime"),
				Type:  utils.StringPointer(utils.MetaVariable),
				Value: utils.StringPointer("~*req.Caller-Channel-Answered-Time")},
			{
				Tag:   utils.StringPointer("Usage"),
				Path:  utils.StringPointer("*cgreq.Usage"),
				Type:  utils.StringPointer(utils.MetaComposed),
				Value: utils.StringPointer("~*req.variable_billsec;s")},
			{
				Tag:   utils.StringPointer("Route"),
				Path:  utils.StringPointer("*cgreq.Route"),
				Type:  utils.StringPointer(utils.MetaVariable),
				Value: utils.StringPointer("~*req.variable_cgr_route")},
			{
				Tag:   utils.StringPointer("Cost"),
				Path:  utils.StringPointer("*cgreq.Cost"),
				Type:  utils.StringPointer(utils.MetaConstant),
				Value: utils.StringPointer("-1.0")},
			{
				Tag:     utils.StringPointer("DisconnectCause"),
				Path:    utils.StringPointer("*cgreq.DisconnectCause"),
				Type:    utils.StringPointer(utils.MetaVariable),
				Filters: &[]string{"*notempty:*req.Hangup-Cause:"},
				Value:   utils.StringPointer("~*req.Hangup-Cause")},
		},
		"*errSip": {
			{
				Tag:       utils.StringPointer("Request"),
				Path:      utils.StringPointer(fmt.Sprintf("%s.Request", utils.MetaRep)),
				Type:      utils.StringPointer(utils.MetaConstant),
				Value:     utils.StringPointer("SIP/2.0 500 Internal Server Error"),
				Mandatory: utils.BoolPointer(true)},
		},
		utils.MetaErr: {
			{
				Tag:       utils.StringPointer("SessionId"),
				Path:      utils.StringPointer(fmt.Sprintf("%s.Session-Id", utils.MetaRep)),
				Type:      utils.StringPointer(utils.MetaVariable),
				Value:     utils.StringPointer("~*req.Session-Id"),
				Mandatory: utils.BoolPointer(true)},
			{
				Tag:       utils.StringPointer("OriginHost"),
				Path:      utils.StringPointer(fmt.Sprintf("%s.Origin-Host", utils.MetaRep)),
				Type:      utils.StringPointer(utils.MetaVariable),
				Value:     utils.StringPointer("~*vars.OriginHost"),
				Mandatory: utils.BoolPointer(true)},
			{
				Tag:       utils.StringPointer("OriginRealm"),
				Path:      utils.StringPointer(fmt.Sprintf("%s.Origin-Realm", utils.MetaRep)),
				Type:      utils.StringPointer(utils.MetaVariable),
				Value:     utils.StringPointer("~*vars.OriginRealm"),
				Mandatory: utils.BoolPointer(true)},
		},
		utils.MetaCCA: {
			{
				Tag:       utils.StringPointer("SessionId"),
				Path:      utils.StringPointer(fmt.Sprintf("%s.Session-Id", utils.MetaRep)),
				Type:      utils.StringPointer(utils.MetaVariable),
				Value:     utils.StringPointer("~*req.Session-Id"),
				Mandatory: utils.BoolPointer(true)},
			{
				Tag:   utils.StringPointer("ResultCode"),
				Path:  utils.StringPointer(fmt.Sprintf("%s.Result-Code", utils.MetaRep)),
				Type:  utils.StringPointer(utils.MetaConstant),
				Value: utils.StringPointer("2001")},
			{
				Tag:       utils.StringPointer("OriginHost"),
				Path:      utils.StringPointer(fmt.Sprintf("%s.Origin-Host", utils.MetaRep)),
				Type:      utils.StringPointer(utils.MetaVariable),
				Value:     utils.StringPointer("~*vars.OriginHost"),
				Mandatory: utils.BoolPointer(true)},
			{
				Tag:       utils.StringPointer("OriginRealm"),
				Path:      utils.StringPointer(fmt.Sprintf("%s.Origin-Realm", utils.MetaRep)),
				Type:      utils.StringPointer(utils.MetaVariable),
				Value:     utils.StringPointer("~*vars.OriginRealm"),
				Mandatory: utils.BoolPointer(true)},
			{
				Tag:       utils.StringPointer("AuthApplicationId"),
				Path:      utils.StringPointer(fmt.Sprintf("%s.Auth-Application-Id", utils.MetaRep)),
				Type:      utils.StringPointer(utils.MetaVariable),
				Value:     utils.StringPointer("~*vars.*appid"),
				Mandatory: utils.BoolPointer(true)},
			{
				Tag:       utils.StringPointer("CCRequestType"),
				Path:      utils.StringPointer(fmt.Sprintf("%s.CC-Request-Type", utils.MetaRep)),
				Type:      utils.StringPointer(utils.MetaVariable),
				Value:     utils.StringPointer("~*req.CC-Request-Type"),
				Mandatory: utils.BoolPointer(true)},
			{
				Tag:       utils.StringPointer("CCRequestNumber"),
				Path:      utils.StringPointer(fmt.Sprintf("%s.CC-Request-Number", utils.MetaRep)),
				Type:      utils.StringPointer(utils.MetaVariable),
				Value:     utils.StringPointer("~*req.CC-Request-Number"),
				Mandatory: utils.BoolPointer(true)},
		},
		utils.MetaASR: {
			{
				Tag:       utils.StringPointer("SessionId"),
				Path:      utils.StringPointer(fmt.Sprintf("%s.Session-Id", utils.MetaDiamreq)),
				Type:      utils.StringPointer(utils.MetaVariable),
				Value:     utils.StringPointer("~*req.Session-Id"),
				Mandatory: utils.BoolPointer(true)},
			{
				Tag:       utils.StringPointer("OriginHost"),
				Path:      utils.StringPointer(fmt.Sprintf("%s.Origin-Host", utils.MetaDiamreq)),
				Type:      utils.StringPointer(utils.MetaVariable),
				Value:     utils.StringPointer("~*req.Destination-Host"),
				Mandatory: utils.BoolPointer(true)},
			{
				Tag:       utils.StringPointer("OriginRealm"),
				Path:      utils.StringPointer(fmt.Sprintf("%s.Origin-Realm", utils.MetaDiamreq)),
				Type:      utils.StringPointer(utils.MetaVariable),
				Value:     utils.StringPointer("~*req.Destination-Realm"),
				Mandatory: utils.BoolPointer(true)},
			{
				Tag:       utils.StringPointer("DestinationRealm"),
				Path:      utils.StringPointer(fmt.Sprintf("%s.Destination-Realm", utils.MetaDiamreq)),
				Type:      utils.StringPointer(utils.MetaVariable),
				Value:     utils.StringPointer("~*req.Origin-Realm"),
				Mandatory: utils.BoolPointer(true)},
			{
				Tag:       utils.StringPointer("DestinationHost"),
				Path:      utils.StringPointer(fmt.Sprintf("%s.Destination-Host", utils.MetaDiamreq)),
				Type:      utils.StringPointer(utils.MetaVariable),
				Value:     utils.StringPointer("~*req.Origin-Host"),
				Mandatory: utils.BoolPointer(true)},
			{
				Tag:       utils.StringPointer("AuthApplicationId"),
				Path:      utils.StringPointer(fmt.Sprintf("%s.Auth-Application-Id", utils.MetaDiamreq)),
				Type:      utils.StringPointer(utils.MetaVariable),
				Value:     utils.StringPointer("~*vars.*appid"),
				Mandatory: utils.BoolPointer(true)},
		},
		utils.MetaRAR: {
			{
				Tag:       utils.StringPointer("SessionId"),
				Path:      utils.StringPointer(fmt.Sprintf("%s.Session-Id", utils.MetaDiamreq)),
				Type:      utils.StringPointer(utils.MetaVariable),
				Value:     utils.StringPointer("~*req.Session-Id"),
				Mandatory: utils.BoolPointer(true)},
			{
				Tag:       utils.StringPointer("OriginHost"),
				Path:      utils.StringPointer(fmt.Sprintf("%s.Origin-Host", utils.MetaDiamreq)),
				Type:      utils.StringPointer(utils.MetaVariable),
				Value:     utils.StringPointer("~*req.Destination-Host"),
				Mandatory: utils.BoolPointer(true)},
			{
				Tag:       utils.StringPointer("OriginRealm"),
				Path:      utils.StringPointer(fmt.Sprintf("%s.Origin-Realm", utils.MetaDiamreq)),
				Type:      utils.StringPointer(utils.MetaVariable),
				Value:     utils.StringPointer("~*req.Destination-Realm"),
				Mandatory: utils.BoolPointer(true)},
			{
				Tag:       utils.StringPointer("DestinationRealm"),
				Path:      utils.StringPointer(fmt.Sprintf("%s.Destination-Realm", utils.MetaDiamreq)),
				Type:      utils.StringPointer(utils.MetaVariable),
				Value:     utils.StringPointer("~*req.Origin-Realm"),
				Mandatory: utils.BoolPointer(true)},
			{
				Tag:       utils.StringPointer("DestinationHost"),
				Path:      utils.StringPointer(fmt.Sprintf("%s.Destination-Host", utils.MetaDiamreq)),
				Type:      utils.StringPointer(utils.MetaVariable),
				Value:     utils.StringPointer("~*req.Origin-Host"),
				Mandatory: utils.BoolPointer(true)},
			{
				Tag:       utils.StringPointer("AuthApplicationId"),
				Path:      utils.StringPointer(fmt.Sprintf("%s.Auth-Application-Id", utils.MetaDiamreq)),
				Type:      utils.StringPointer(utils.MetaVariable),
				Value:     utils.StringPointer("~*vars.*appid"),
				Mandatory: utils.BoolPointer(true)},
			{
				Tag:   utils.StringPointer("ReAuthRequestType"),
				Path:  utils.StringPointer(fmt.Sprintf("%s.Re-Auth-Request-Type", utils.MetaDiamreq)),
				Type:  utils.StringPointer(utils.MetaConstant),
				Value: utils.StringPointer("0"),
			},
		},
		utils.MetaDMR: {
			{
				Tag:   utils.StringPointer("User-Name"),
				Path:  utils.StringPointer(fmt.Sprintf("%s.User-Name", utils.MetaRadDAReq)),
				Type:  utils.StringPointer(utils.MetaVariable),
				Value: utils.StringPointer("~*oreq.User-Name"),
			},
			{
				Tag:   utils.StringPointer("NAS-IP-Address"),
				Path:  utils.StringPointer(fmt.Sprintf("%s.NAS-IP-Address", utils.MetaRadDAReq)),
				Type:  utils.StringPointer(utils.MetaVariable),
				Value: utils.StringPointer("~*oreq.NAS-IP-Address"),
			},
			{
				Tag:   utils.StringPointer("Acct-Session-Id"),
				Path:  utils.StringPointer(fmt.Sprintf("%s.Acct-Session-Id", utils.MetaRadDAReq)),
				Type:  utils.StringPointer(utils.MetaVariable),
				Value: utils.StringPointer("~*oreq.Acct-Session-Id"),
			},
			{
				Tag:   utils.StringPointer("Reply-Message"),
				Path:  utils.StringPointer(fmt.Sprintf("%s.Reply-Message", utils.MetaRadDAReq)),
				Type:  utils.StringPointer(utils.MetaVariable),
				Value: utils.StringPointer("~*req.DisconnectCause"),
			},
		},
		utils.MetaCoA: {
			{
				Tag:   utils.StringPointer("User-Name"),
				Path:  utils.StringPointer(fmt.Sprintf("%s.User-Name", utils.MetaRadDAReq)),
				Type:  utils.StringPointer(utils.MetaVariable),
				Value: utils.StringPointer("~*oreq.User-Name"),
			},
			{
				Tag:   utils.StringPointer("NAS-IP-Address"),
				Path:  utils.StringPointer(fmt.Sprintf("%s.NAS-IP-Address", utils.MetaRadDAReq)),
				Type:  utils.StringPointer(utils.MetaVariable),
				Value: utils.StringPointer("~*oreq.NAS-IP-Address"),
			},
			{
				Tag:   utils.StringPointer("Acct-Session-Id"),
				Path:  utils.StringPointer(fmt.Sprintf("%s.Acct-Session-Id", utils.MetaRadDAReq)),
				Type:  utils.StringPointer(utils.MetaVariable),
				Value: utils.StringPointer("~*oreq.Acct-Session-Id"),
			},
			{
				Tag:   utils.StringPointer("Filter-Id"),
				Path:  utils.StringPointer(fmt.Sprintf("%s.Filter-Id", utils.MetaRadDAReq)),
				Type:  utils.StringPointer(utils.MetaVariable),
				Value: utils.StringPointer("~*req.CustomFilter"),
			},
		},
		utils.MetaCdrLog: {
			{
				Tag:       utils.StringPointer("ToR"),
				Path:      utils.StringPointer("*cdr.ToR"),
				Type:      utils.StringPointer(utils.MetaVariable),
				Value:     utils.StringPointer("~*req.BalanceType"),
				Mandatory: utils.BoolPointer(true),
			},
			{
				Tag:       utils.StringPointer("OriginHost"),
				Path:      utils.StringPointer("*cdr.OriginHost"),
				Type:      utils.StringPointer(utils.MetaConstant),
				Value:     utils.StringPointer("127.0.0.1"),
				Mandatory: utils.BoolPointer(true),
			},
			{
				Tag:       utils.StringPointer("RequestType"),
				Path:      utils.StringPointer("*cdr.RequestType"),
				Type:      utils.StringPointer(utils.MetaConstant),
				Value:     utils.StringPointer(utils.MetaNone),
				Mandatory: utils.BoolPointer(true),
			},
			{
				Tag:       utils.StringPointer("Tenant"),
				Path:      utils.StringPointer("*cdr.Tenant"),
				Type:      utils.StringPointer(utils.MetaVariable),
				Value:     utils.StringPointer("~*req.Tenant"),
				Mandatory: utils.BoolPointer(true),
			},
			{
				Tag:       utils.StringPointer("Account"),
				Path:      utils.StringPointer("*cdr.Account"),
				Type:      utils.StringPointer(utils.MetaVariable),
				Value:     utils.StringPointer("~*req.Account"),
				Mandatory: utils.BoolPointer(true),
			},
			{
				Tag:       utils.StringPointer("Subject"),
				Path:      utils.StringPointer("*cdr.Subject"),
				Type:      utils.StringPointer(utils.MetaVariable),
				Value:     utils.StringPointer("~*req.Account"),
				Mandatory: utils.BoolPointer(true),
			},
			{
				Tag:       utils.StringPointer("Cost"),
				Path:      utils.StringPointer("*cdr.Cost"),
				Type:      utils.StringPointer(utils.MetaVariable),
				Value:     utils.StringPointer("~*req.Cost"),
				Mandatory: utils.BoolPointer(true),
			},
			{
				Tag:       utils.StringPointer("Source"),
				Path:      utils.StringPointer("*cdr.Source"),
				Type:      utils.StringPointer(utils.MetaConstant),
				Value:     utils.StringPointer(utils.MetaCdrLog),
				Mandatory: utils.BoolPointer(true),
			},
			{
				Tag:       utils.StringPointer("Usage"),
				Path:      utils.StringPointer("*cdr.Usage"),
				Type:      utils.StringPointer(utils.MetaConstant),
				Value:     utils.StringPointer("1"),
				Mandatory: utils.BoolPointer(true),
			},
			{
				Tag:       utils.StringPointer("RunID"),
				Path:      utils.StringPointer("*cdr.RunID"),
				Type:      utils.StringPointer(utils.MetaVariable),
				Value:     utils.StringPointer("~*req.ActionType"),
				Mandatory: utils.BoolPointer(true),
			},
			{
				Tag:       utils.StringPointer("SetupTime"),
				Path:      utils.StringPointer("*cdr.SetupTime"),
				Type:      utils.StringPointer(utils.MetaConstant),
				Value:     utils.StringPointer("*now"),
				Mandatory: utils.BoolPointer(true),
			},
			{
				Tag:       utils.StringPointer("AnswerTime"),
				Path:      utils.StringPointer("*cdr.AnswerTime"),
				Type:      utils.StringPointer(utils.MetaConstant),
				Value:     utils.StringPointer("*now"),
				Mandatory: utils.BoolPointer(true),
			},
			{
				Tag:       utils.StringPointer("PreRated"),
				Path:      utils.StringPointer("*cdr.PreRated"),
				Type:      utils.StringPointer(utils.MetaConstant),
				Value:     utils.StringPointer("true"),
				Mandatory: utils.BoolPointer(true),
			},
		},
	}
	dfCgrJSONCfg, err := NewCgrJsonCfgFromBytes([]byte(CGRATES_CFG_JSON))
	if err != nil {
		t.Error(err)
	}
	cfg := make(FcTemplatesJsonCfg)
	if err := dfCgrJSONCfg.GetSection(context.Background(), TemplatesJSON, &cfg); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Errorf("Expected: %+v \n,received: %+v", utils.ToJSON(eCfg), utils.ToJSON(cfg))
	}
}

func TestDfActionSJsonCfg(t *testing.T) {
	eCfg := &ActionSJsonCfg{
		Enabled:                   utils.BoolPointer(false),
		Cdrs_conns:                &[]string{},
		Ees_conns:                 &[]string{},
		Thresholds_conns:          &[]string{},
		Stats_conns:               &[]string{},
		Accounts_conns:            &[]string{},
		Admins_conns:              &[]string{},
		Tenants:                   &[]string{},
		Indexed_selects:           utils.BoolPointer(true),
		String_indexed_fields:     nil,
		Prefix_indexed_fields:     &[]string{},
		Suffix_indexed_fields:     &[]string{},
		Exists_indexed_fields:     &[]string{},
		Notexists_indexed_fields:  &[]string{},
		Nested_fields:             utils.BoolPointer(false),
		Dynaprepaid_actionprofile: &[]string{},
		Opts:                      &ActionsOptsJson{},
	}
	dfCgrJSONCfg, err := NewCgrJsonCfgFromBytes([]byte(CGRATES_CFG_JSON))
	if err != nil {
		t.Error(err)
	}
	cfg := new(ActionSJsonCfg)
	if err := dfCgrJSONCfg.GetSection(context.Background(), ActionSJSON, cfg); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Errorf("\n Expected <%+v>,\nReceived:<%+v>", utils.ToJSON(eCfg), utils.ToJSON(cfg))
	}
}

func TestSetSection(t *testing.T) {
	jsn := `
		{
			"general": {
				"Node_id":2,
			},
		}
	`
	jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(jsn))
	if err != nil {
		t.Error(err)
	}
	payload := make(chan struct{})
	errExpect := "json: unsupported type: chan struct {}"
	if err := jsnCfg.SetSection(&context.Context{}, "general", payload); err == nil || err.Error() != errExpect {
		t.Error(err)
	}
}

func TestConfigJsonCloneSection(t *testing.T) {
	s := Sections{
		&CoreSCfg{
			Caps:              2,
			CapsStrategy:      "*busy",
			CapsStatsInterval: 2 * time.Second,
			ShutdownTimeout:   3 * time.Second,
		},
	}

	exp := []Section{
		&CoreSCfg{
			Caps:              2,
			CapsStrategy:      "*busy",
			CapsStatsInterval: 2 * time.Second,
			ShutdownTimeout:   3 * time.Second,
		},
	}

	c := s.Clone()
	if !reflect.DeepEqual(exp[0], c[0]) {
		t.Errorf("Expected %v \n bu received \n %v", exp, c)
	}
}
