//go:build !app_v1
package simapp
import (
    
	_ "embed"
    "io"
    "os"
    "path/filepath"
    "github.com/tendermint/tendermint/libs/log"
	dbm "github.com/tendermint/tm-db"
    "cosmossdk.io/depinject"
    "github.com/cosmos/cosmos-sdk/baseapp"
    "github.com/cosmos/cosmos-sdk/client"
    "github.com/cosmos/cosmos-sdk/codec"
	codectypes "github.com/cosmos/cosmos-sdk/codec/types"
    "github.com/cosmos/cosmos-sdk/runtime"
    "github.com/cosmos/cosmos-sdk/server"
    "github.com/cosmos/cosmos-sdk/server/api"
    "github.com/cosmos/cosmos-sdk/server/config"
	servertypes "github.com/cosmos/cosmos-sdk/server/types"
    "github.com/cosmos/cosmos-sdk/store/streaming"
	storetypes "github.com/cosmos/cosmos-sdk/store/types"
    "github.com/cosmos/cosmos-sdk/testutil/testdata_pulsar"
    "github.com/cosmos/cosmos-sdk/types/module"
    "github.com/cosmos/cosmos-sdk/x/auth"
	authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
	authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation"
	_ "github.com/cosmos/cosmos-sdk/x/auth/tx/config" // import for side-effects
	authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
    "github.com/cosmos/cosmos-sdk/x/auth/vesting"
	authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper"
	authzmodule "github.com/cosmos/cosmos-sdk/x/authz/module"
    "github.com/cosmos/cosmos-sdk/x/bank"
	bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
    "github.com/cosmos/cosmos-sdk/x/capability"
	capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper"
	consensus "github.com/cosmos/cosmos-sdk/x/consensus"
	consensuskeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper"
    "github.com/cosmos/cosmos-sdk/x/crisis"
	crisiskeeper "github.com/cosmos/cosmos-sdk/x/crisis/keeper"
	distr "github.com/cosmos/cosmos-sdk/x/distribution"
	distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper"
    "github.com/cosmos/cosmos-sdk/x/evidence"
	evidencekeeper "github.com/cosmos/cosmos-sdk/x/evidence/keeper"
	feegrantkeeper "github.com/cosmos/cosmos-sdk/x/feegrant/keeper"
	feegrantmodule "github.com/cosmos/cosmos-sdk/x/feegrant/module"
    "github.com/cosmos/cosmos-sdk/x/genutil"
	genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
    "github.com/cosmos/cosmos-sdk/x/gov"
	govclient "github.com/cosmos/cosmos-sdk/x/gov/client"
	govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper"
	groupkeeper "github.com/cosmos/cosmos-sdk/x/group/keeper"
	groupmodule "github.com/cosmos/cosmos-sdk/x/group/module"
    "github.com/cosmos/cosmos-sdk/x/mint"
	mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper"
	nftkeeper "github.com/cosmos/cosmos-sdk/x/nft/keeper"
	nftmodule "github.com/cosmos/cosmos-sdk/x/nft/module"
    "github.com/cosmos/cosmos-sdk/x/params"
	paramsclient "github.com/cosmos/cosmos-sdk/x/params/client"
	paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper"
	paramstypes "github.com/cosmos/cosmos-sdk/x/params/types"
    "github.com/cosmos/cosmos-sdk/x/slashing"
	slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper"
    "github.com/cosmos/cosmos-sdk/x/staking"
	stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
    "github.com/cosmos/cosmos-sdk/x/upgrade"
	upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client"
	upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper"
)
var (
	// DefaultNodeHome default home directories for the application daemon
	DefaultNodeHome string
	// ModuleBasics defines the module BasicManager is in charge of setting up basic,
	// non-dependant module elements, such as codec registration
	// and genesis verification.
	ModuleBasics = module.NewBasicManager(
		auth.AppModuleBasic{
},
		genutil.NewAppModuleBasic(genutiltypes.DefaultMessageValidator),
		bank.AppModuleBasic{
},
		capability.AppModuleBasic{
},
		staking.AppModuleBasic{
},
		mint.AppModuleBasic{
},
		distr.AppModuleBasic{
},
		gov.NewAppModuleBasic(
			[]govclient.ProposalHandler{
    paramsclient.ProposalHandler,
				upgradeclient.LegacyProposalHandler,
				upgradeclient.LegacyCancelProposalHandler,
},
		),
		params.AppModuleBasic{
},
		crisis.AppModuleBasic{
},
		slashing.AppModuleBasic{
},
		feegrantmodule.AppModuleBasic{
},
		upgrade.AppModuleBasic{
},
		evidence.AppModuleBasic{
},
		authzmodule.AppModuleBasic{
},
		groupmodule.AppModuleBasic{
},
		vesting.AppModuleBasic{
},
		nftmodule.AppModuleBasic{
},
		consensus.AppModuleBasic{
},
	)
)
var (
	_ runtime.AppI            = (*SimApp)(nil)
	_ servertypes.Application = (*SimApp)(nil)
)
// SimApp extends an ABCI application, but with most of its parameters exported.
// They are exported for convenience in creating helper functions, as object
// capabilities aren't needed for testing.
type SimApp struct {
	*runtime.App
	legacyAmino       *codec.LegacyAmino
	appCodec          codec.Codec
	txConfig          client.TxConfig
	interfaceRegistry codectypes.InterfaceRegistry
	// keepers
	AccountKeeper         authkeeper.AccountKeeper
	BankKeeper            bankkeeper.Keeper
	CapabilityKeeper      *capabilitykeeper.Keeper
	StakingKeeper         *stakingkeeper.Keeper
	SlashingKeeper        slashingkeeper.Keeper
	MintKeeper            mintkeeper.Keeper
	DistrKeeper           distrkeeper.Keeper
	GovKeeper             *govkeeper.Keeper
	CrisisKeeper          *crisiskeeper.Keeper
	UpgradeKeeper         *upgradekeeper.Keeper
	ParamsKeeper          paramskeeper.Keeper
	AuthzKeeper           authzkeeper.Keeper
	EvidenceKeeper        evidencekeeper.Keeper
	FeeGrantKeeper        feegrantkeeper.Keeper
	GroupKeeper           groupkeeper.Keeper
	NFTKeeper             nftkeeper.Keeper
	ConsensusParamsKeeper consensuskeeper.Keeper
	// simulation manager
	sm *module.SimulationManager
}
func init() {
    userHomeDir, err := os.UserHomeDir()
    if err != nil {
    panic(err)
}
DefaultNodeHome = filepath.Join(userHomeDir, ".simapp")
}
// NewSimApp returns a reference to an initialized SimApp.
func NewSimApp(
	logger log.Logger,
	db dbm.DB,
	traceStore io.Writer,
	loadLatest bool,
	appOpts servertypes.AppOptions,
	baseAppOptions ...func(*baseapp.BaseApp),
) *SimApp {
    var (
		app        = &SimApp{
}
appBuilder *runtime.AppBuilder
		// Below we could construct and set an application specific mempool and ABCI 1.0 Prepare and Process Proposal
		// handlers. These defaults are already set in the SDK's BaseApp, this shows an example of how to override
		// them.
		//
		// nonceMempool = mempool.NewSenderNonceMempool()
		// mempoolOpt   = baseapp.SetMempool(nonceMempool)
		// prepareOpt   = func(app *baseapp.BaseApp) {
		// 	app.SetPrepareProposal(app.DefaultPrepareProposal())
		//
}
		// processOpt = func(app *baseapp.BaseApp) {
		// 	app.SetProcessProposal(app.DefaultProcessProposal())
		//
}
		//
		// Further down we'd set the options in the AppBuilder like below.
		// baseAppOptions = append(baseAppOptions, mempoolOpt, prepareOpt, processOpt)
		// merge the AppConfig and other configuration in one config
		appConfig = depinject.Configs(
			AppConfig,
			depinject.Supply(
				// supply the application options
				appOpts,
				// ADVANCED CONFIGURATION
				//
				// AUTH
				//
				// For providing a custom function required in auth to generate custom account types
				// add it below. By default the auth module uses simulation.RandomGenesisAccounts.
				//
				// authtypes.RandomGenesisAccountsFn(simulation.RandomGenesisAccounts),
				// For providing a custom a base account type add it below.
				// By default the auth module uses authtypes.ProtoBaseAccount().
				//
				// func()
authtypes.AccountI {
    return authtypes.ProtoBaseAccount()
},
				//
				// MINT
				//
				// For providing a custom inflation function for x/mint add here your
				// custom function that implements the minttypes.InflationCalculationFn
				// interface.
			),
		)
	)
    if err := depinject.Inject(appConfig,
		&appBuilder,
		&app.appCodec,
		&app.legacyAmino,
		&app.txConfig,
		&app.interfaceRegistry,
		&app.AccountKeeper,
		&app.BankKeeper,
		&app.CapabilityKeeper,
		&app.StakingKeeper,
		&app.SlashingKeeper,
		&app.MintKeeper,
		&app.DistrKeeper,
		&app.GovKeeper,
		&app.CrisisKeeper,
		&app.UpgradeKeeper,
		&app.ParamsKeeper,
		&app.AuthzKeeper,
		&app.EvidenceKeeper,
		&app.FeeGrantKeeper,
		&app.GroupKeeper,
		&app.NFTKeeper,
		&app.ConsensusParamsKeeper,
	); err != nil {
    panic(err)
}
app.App = appBuilder.Build(logger, db, traceStore, baseAppOptions...)
	// load state streaming if enabled
    if _, _, err := streaming.LoadStreamingServices(app.App.BaseApp, appOpts, app.appCodec, logger, app.kvStoreKeys()); err != nil {
    logger.Error("failed to load state streaming", "err", err)
os.Exit(1)
}
	/****  Module Options ****/
	app.ModuleManager.RegisterInvariants(app.CrisisKeeper)
	// RegisterUpgradeHandlers is used for registering any on-chain upgrades.
	app.RegisterUpgradeHandlers()
	// add test gRPC service for testing gRPC queries in isolation
	testdata_pulsar.RegisterQueryServer(app.GRPCQueryRouter(), testdata_pulsar.QueryImpl{
})
	// create the simulation manager and define the order of the modules for deterministic simulations
	//
	// NOTE: this is not required apps that don't use the simulator for fuzz testing
	// transactions
    overrideModules := map[string]module.AppModuleSimulation{
    authtypes.ModuleName: auth.NewAppModule(app.appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts, app.GetSubspace(authtypes.ModuleName)),
}
app.sm = module.NewSimulationManagerFromAppModules(app.ModuleManager.Modules, overrideModules)
app.sm.RegisterStoreDecoders()
	// A custom InitChainer can be set if extra pre-init-genesis logic is required.
	// By default, when using app wiring enabled module, this is not required.
	// For instance, the upgrade module will set automatically the module version map in its init genesis thanks to app wiring.
	// However, when registering a module manually (i.e. that does not support app wiring), the module version map
	// must be set manually as follow. The upgrade module will de-duplicate the module version map.
	//
	// app.SetInitChainer(func(ctx sdk.Context, req abci.RequestInitChain)
abci.ResponseInitChain {
	// 	app.UpgradeKeeper.SetModuleVersionMap(ctx, app.ModuleManager.GetVersionMap())
	// 	return app.App.InitChainer(ctx, req)
	//
})
    if err := app.Load(loadLatest); err != nil {
    panic(err)
}
return app
}
// Name returns the name of the App
func (app *SimApp)
Name()
string {
    return app.BaseApp.Name()
}
// LegacyAmino returns SimApp's amino codec.
//
// NOTE: This is solely to be used for testing purposes as it may be desirable
// for modules to register their own custom testing types.
func (app *SimApp)
LegacyAmino() *codec.LegacyAmino {
    return app.legacyAmino
}
// AppCodec returns SimApp's app codec.
//
// NOTE: This is solely to be used for testing purposes as it may be desirable
// for modules to register their own custom testing types.
func (app *SimApp)
AppCodec()
codec.Codec {
    return app.appCodec
}
// InterfaceRegistry returns SimApp's InterfaceRegistry
func (app *SimApp)
InterfaceRegistry()
codectypes.InterfaceRegistry {
    return app.interfaceRegistry
}
// TxConfig returns SimApp's TxConfig
func (app *SimApp)
TxConfig()
client.TxConfig {
    return app.txConfig
}
// GetKey returns the KVStoreKey for the provided store key.
//
// NOTE: This is solely to be used for testing purposes.
func (app *SimApp)
GetKey(storeKey string) *storetypes.KVStoreKey {
    sk := app.UnsafeFindStoreKey(storeKey)
kvStoreKey, ok := sk.(*storetypes.KVStoreKey)
    if !ok {
    return nil
}
return kvStoreKey
}
func (app *SimApp)
kvStoreKeys()
map[string]*storetypes.KVStoreKey {
    keys := make(map[string]*storetypes.KVStoreKey)
    for _, k := range app.GetStoreKeys() {
    if kv, ok := k.(*storetypes.KVStoreKey); ok {
    keys[kv.Name()] = kv
}
	
}
return keys
}
// GetSubspace returns a param subspace for a given module name.
//
// NOTE: This is solely to be used for testing purposes.
func (app *SimApp)
GetSubspace(moduleName string)
paramstypes.Subspace {
    subspace, _ := app.ParamsKeeper.GetSubspace(moduleName)
return subspace
}
// SimulationManager implements the SimulationApp interface
func (app *SimApp)
SimulationManager() *module.SimulationManager {
    return app.sm
}
// RegisterAPIRoutes registers all application module routes with the provided
// API server.
func (app *SimApp)
RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig) {
    app.App.RegisterAPIRoutes(apiSvr, apiConfig)
	// register swagger API in app.go so that other applications can override easily
    if err := server.RegisterSwaggerAPI(apiSvr.ClientCtx, apiSvr.Router, apiConfig.Swagger); err != nil {
    panic(err)
}
}
// GetMaccPerms returns a copy of the module account permissions
//
// NOTE: This is solely to be used for testing purposes.
func GetMaccPerms()
map[string][]string {
    dup := make(map[string][]string)
    for _, perms := range moduleAccPerms {
    dup[perms.Account] = perms.Permissions
}
return dup
}
// BlockedAddresses returns all the app's blocked account addresses.
func BlockedAddresses()
map[string]bool {
    result := make(map[string]bool)
    if len(blockAccAddrs) > 0 {
    for _, addr := range blockAccAddrs {
    result[addr] = true
}
	
}
else {
    for addr := range GetMaccPerms() {
    result[addr] = true
}
	
}
return result
}