package <%= moduleName %>

import (
	"cosmossdk.io/core/address"
	"cosmossdk.io/core/appmodule"
	"cosmossdk.io/core/store"
	"cosmossdk.io/depinject"
	"cosmossdk.io/depinject/appconfig"
	"cosmossdk.io/log"
	"github.com/cosmos/cosmos-sdk/codec"
	authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
	ibckeeper "github.com/cosmos/ibc-go/v10/modules/core/keeper"<% } %>

	"<%= modulePath %>/x/<%= moduleName %>/keeper"
	"<%= modulePath %>/x/<%= moduleName %>/types"
)

var _ depinject.OnePerModuleType = AppModule{}

// IsOnePerModuleType implements the depinject.OnePerModuleType interface.
func (AppModule) IsOnePerModuleType() {}

func init() {
	appconfig.Register(
	    &types.Module{},
		appconfig.Provide(ProvideModule),
	)
}

type ModuleInputs struct {
	depinject.In

	Config       *types.Module
	StoreService  store.KVStoreService
	Cdc          codec.Codec
	AddressCodec address.Codec

	AuthKeeper types.AuthKeeper
	BankKeeper types.BankKeeper<%= for (dependency) in dependencies { %><%= if (dependency.Name != "Bank" && dependency.Name != "Auth") { %>
    <%= dependency.KeeperName() %> types.<%= dependency.KeeperName() %><% } %><% } %>

    <%= if (isIBC) { %>IBCKeeperFn func() *ibckeeper.Keeper `optional:"true"` <% } %>
}

type ModuleOutputs struct {
	depinject.Out

	<%= title(moduleName) %>Keeper keeper.Keeper
	Module appmodule.AppModule
}

func ProvideModule(in ModuleInputs) ModuleOutputs {
	// default to governance authority if not provided
	authority := authtypes.NewModuleAddress(types.GovModuleName)
	if in.Config.Authority != "" {
		authority = authtypes.NewModuleAddressOrBech32Address(in.Config.Authority)
	}
	k := keeper.NewKeeper(
		in.StoreService,
	    in.Cdc,
		in.AddressCodec,
	    authority, <%= if (isIBC) { %>
		in.IBCKeeperFn,<% } %><%= for (dependency) in dependencies { %>
        in.<%= dependency.KeeperName() %>,<% } %>
	)
	m := NewAppModule(in.Cdc, k, in.AuthKeeper, in.BankKeeper)

	return ModuleOutputs{<%= title(moduleName) %>Keeper: k, Module: m}
}
