/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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
 *
 *     http://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 server

import (
	"context"
	"crypto/tls"
	"os"

	"github.com/apache/servicecomb-service-center/server/middleware"
	"github.com/apache/servicecomb-service-center/server/resource/disco"
	syncv1 "github.com/apache/servicecomb-service-center/syncer/api/v1"
	"github.com/apache/servicecomb-service-center/syncer/rpc"
	"github.com/gofiber/fiber/v2"

	"github.com/go-chassis/go-chassis/v2"
	chassisServer "github.com/go-chassis/go-chassis/v2/core/server"

	"github.com/apache/servicecomb-service-center/datasource"
	nf "github.com/apache/servicecomb-service-center/pkg/event"
	"github.com/apache/servicecomb-service-center/pkg/log"
	"github.com/apache/servicecomb-service-center/pkg/plugin"
	"github.com/apache/servicecomb-service-center/pkg/signal"
	"github.com/apache/servicecomb-service-center/server/alarm"
	"github.com/apache/servicecomb-service-center/server/command"
	"github.com/apache/servicecomb-service-center/server/config"
	"github.com/apache/servicecomb-service-center/server/event"
	"github.com/apache/servicecomb-service-center/server/plugin/security/tlsconf"
	"github.com/apache/servicecomb-service-center/server/service/grc"
	"github.com/apache/servicecomb-service-center/server/service/rbac"
	syncConfig "github.com/apache/servicecomb-service-center/syncer/config"
	"github.com/go-chassis/foundation/gopool"
)

var sc ServiceCenterServer

func Run() {
	if err := command.ParseConfig(os.Args); err != nil {
		log.Fatal(err.Error(), err)
	}
	sc.Run()
}

type endpoint struct {
	Host string
	Port string
}

type ServiceCenterServer struct {
	Endpoint    endpoint
	APIServer   *APIServer
	eventCenter *nf.BusService
}

func (s *ServiceCenterServer) Run() {
	s.initialize()

	s.startServices()

	s.startChassis()

	signal.RegisterListener()

	s.waitForQuit()
}

func (s *ServiceCenterServer) startChassis() {
	go func() {
		mask := make([]string, 0)
		if !syncConfig.GetConfig().Sync.EnableOnStart {
			mask = append(mask, "grpc")
		} else {
			chassis.RegisterSchema("grpc", &rpc.Server{},
				chassisServer.WithRPCServiceDesc(&syncv1.EventService_ServiceDesc))
		}
		if !config.GetBool("server.turbo", false) {
			log.Info("turbo is disabled")
			mask = append(mask, "rest")
		} else {
			app := fiber.New(fiber.Config{})

			app.Use(middleware.PrepareContextFor)

			app.Post("/v4/:project/registry/microservices/:serviceId/instances",
				disco.FiberRegisterInstance)
			app.Put("/v4/:project/registry/microservices/:serviceId/instances/:instanceId/heartbeat",
				disco.FiberSendHeartbeat)
			app.Get("/v4/:project/registry/instances", disco.FiberFindInstances)
			chassis.RegisterSchema("rest", app)
			log.Info("turbo is enabled")
		}
		if err := chassis.Run(chassisServer.WithServerMask(mask...)); err != nil {
			log.Warn(err.Error())
		}
	}()
}

func (s *ServiceCenterServer) waitForQuit() {
	err := <-s.APIServer.Err()
	if err != nil {
		log.Error("service center catch errors", err)
	}

	s.Stop()
}

func (s *ServiceCenterServer) initialize() {
	s.initEndpoints()
	// SSL
	s.initSSL()
	// Datasource
	s.initDatasource()
	s.APIServer = GetAPIServer()
	s.eventCenter = event.Center()
}

func (s *ServiceCenterServer) initEndpoints() {
	s.Endpoint.Host = config.GetString("server.host", "127.0.0.1", config.WithStandby("httpaddr"))
	s.Endpoint.Port = config.GetString("server.port", "30100", config.WithStandby("httpport"))
}

func (s *ServiceCenterServer) initDatasource() {
	// init datasource
	kind := config.GetString("registry.kind", "", config.WithStandby("registry_plugin"))
	tlsConfig, err := getDatasourceTLSConfig()
	if err != nil {
		log.Fatal("get datasource tlsConfig failed", err)
	}
	if err := datasource.Init(datasource.Options{
		Kind:       kind,
		Logger:     log.Logger,
		SslEnabled: config.GetSSL().SslEnabled,
		TLSConfig:  tlsConfig,
		ConnectedFunc: func() {
			err := alarm.Clear(alarm.IDBackendConnectionRefuse)
			if err != nil {
				log.Error("", err)
			}
		},
		ErrorFunc: func(err error) {
			if err == nil {
				return
			}
			err = alarm.Raise(alarm.IDBackendConnectionRefuse, alarm.AdditionalContext("%v", err))
			if err != nil {
				log.Error("", err)
			}
		},
		EnableCache: config.GetRegistry().EnableCache,
		InstanceTTL: config.GetRegistry().InstanceTTL,
	}); err != nil {
		log.Fatal("init datasource failed", err)
	}
}

func getDatasourceTLSConfig() (*tls.Config, error) {
	if config.GetSSL().SslEnabled {
		return tlsconf.ClientConfig()
	}
	return nil, nil
}

func (s *ServiceCenterServer) initSSL() {
	if !config.GetSSL().SslEnabled {
		return
	}
	options := tlsconf.Options{
		Dir:              config.GetString("ssl.dir", "", config.WithENV("SSL_ROOT")),
		MinVersion:       config.GetString("ssl.minVersion", "TLSv1.2", config.WithStandby("ssl_min_version")),
		ClientMinVersion: config.GetString("ssl.client.minVersion", "", config.WithStandby("ssl_client_min_version")),
		VerifyPeer:       config.GetInt("ssl.verifyClient", 1, config.WithStandby("ssl_verify_client")) != 0,
		Ciphers:          config.GetString("ssl.ciphers", "", config.WithStandby("ssl_ciphers")),
		ClientCiphers:    config.GetString("ssl.client.ciphers", "", config.WithStandby("ssl_client_ciphers")),
	}
	if options.ClientMinVersion == "" {
		options.ClientMinVersion = options.MinVersion
	}
	if options.ClientCiphers == "" {
		options.ClientCiphers = options.Ciphers
	}
	if err := tlsconf.Init(options); err != nil {
		log.Fatal("init ssl failed", err)
	}
}

func (s *ServiceCenterServer) startServices() {
	// notifications
	s.eventCenter.Start()

	// load sc plugins
	plugin.LoadPlugins()
	rbac.Init()
	if err := grc.Init(); err != nil {
		log.Fatal("init gov failed", err)
	}
	// check version
	if config.GetRegistry().SelfRegister {
		if err := datasource.GetSCManager().UpgradeVersion(context.Background()); err != nil {
			os.Exit(1)
		}
	}
	// api service
	s.startAPIService()
}

func (s *ServiceCenterServer) startAPIService() {
	s.APIServer.SetHostPort(s.Endpoint.Host, s.Endpoint.Port)
	s.APIServer.Start()
}

func (s *ServiceCenterServer) Stop() {
	if s.APIServer != nil {
		s.APIServer.Stop()
	}

	if s.eventCenter != nil {
		s.eventCenter.Stop()
	}

	gopool.CloseAndWait()

	log.Warn("service center stopped")
	log.Flush()
}
