text: /*
   * Copyright 2018 It-chain
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   * https://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package ivmfx
  
  import (
  	"context"
  
  	"github.com/it-chain/engine/common/rabbitmq/pubsub"
  	"github.com/it-chain/engine/common/rabbitmq/rpc"
  	"github.com/it-chain/engine/conf"
  	"github.com/it-chain/engine/ivm"
  	"github.com/it-chain/engine/ivm/api"
  	"github.com/it-chain/engine/ivm/infra/adapter"
  	"github.com/it-chain/engine/ivm/infra/git"
  	"github.com/it-chain/engine/ivm/infra/tesseract"
  	"github.com/it-chain/iLogger"
  	"go.uber.org/fx"
  )
  
  var Module = fx.Options(
  	fx.Provide(
  		NewGitReposutoryService,
  		NewContainerService,
  		api.NewICodeApi,
  		adapter.NewDeployCommandHandler,
  		adapter.NewUnDeployCommandHandler,
  		adapter.NewIcodeExecuteCommandHandler,
  		adapter.NewListCommandHandler,
  		adapter.NewBlockCommittedEventHandler,
  	),
  	fx.Invoke(
  		RegisterRpcHandlers,
  		RegisterPubsubHandlers,
  		RegisterTearDown,
  	),
  )
  
  func NewGitReposutoryService() ivm.GitService {
  	return git.NewRepositoryService()
  }
  
  func NewContainerService(conf *conf.Configuration) ivm.ContainerService {
  	if conf.Docker.Use {
  		cs, err := tesseract.NewContainerService(&tesseract.ContainerDockerConfig{
  			Subnet:      conf.Docker.NetworkSubnet,
  			VolumeName:  conf.Docker.VolumeName,
  			NetworkName: conf.Docker.NetworkName,
  		})
  		if err != nil {
  			panic(err)
  		}
  		return cs
  	} else {
  		cs, err := tesseract.NewContainerService(nil)
  		if err != nil {
  			panic(err)
  		}
  		return cs
  	}
  
  }
  
  func RegisterRpcHandlers(
  	server *rpc.Server,
  	executeCommandHandler *adapter.IcodeExecuteCommandHandler,
  	listCommandHandler *adapter.ListCommandHandler,
  	deployCommandHandler *adapter.DeployCommandHandler,
  	unDeployCommandHandler *adapter.UnDeployCommandHandler,
  ) {
  
  	if err := server.Register("ivm.execute", executeCommandHandler.HandleTransactionExecuteCommandHandler); err != nil {
  		panic(err)
  	}
  	if err := server.Register("ivm.deploy", deployCommandHandler.HandleDeployCommand); err != nil {
  		panic(err)
  	}
  	if err := server.Register("ivm.undeploy", unDeployCommandHandler.HandleUnDeployCommand); err != nil {
  		panic(err)
  	}
  	if err := server.Register("ivm.list", listCommandHandler.HandleListCommand); err != nil {
  		panic(err)
  	}
  }
  
  func RegisterPubsubHandlers(subscriber *pubsub.TopicSubscriber, handler *adapter.BlockCommittedEventHandler) {
  	iLogger.Infof(nil, "[Main] Ivm is starting")
  	if err := subscriber.SubscribeTopic("block.*", handler); err != nil {
  		panic(err)
  	}
  }
  
  func RegisterTearDown(lifecycle fx.Lifecycle, containerService ivm.ContainerService) {
  	lifecycle.Append(fx.Hook{
  		OnStart: func(context context.Context) error {
  			return nil
  		},
  		OnStop: func(context context.Context) error {
  			iCodeInfos := containerService.GetRunningICodeList()
  			for _, iCodeInfo := range iCodeInfos {
  				containerService.StopContainer(iCodeInfo.ID)
  			}
  			return nil
  		},
  	})
  }
  