package api

import (
	"context"
	"rpirelay/config"
	"rpirelay/internal/api/relay"
	rt "rpirelay/internal/api/relay/transport"
	cc "rpirelay/internal/context"
	"rpirelay/internal/middleware"
	"rpirelay/internal/server"

	"github.com/stianeikeland/go-rpio/v4"
)

func Start(ctx context.Context, cfg *config.Config) chan error {
	errChan := make(chan error, 0)

	go func() {
		if err := startAPIServer(ctx, cfg); err != nil {
			errChan <- err
			return
		}
		close(errChan)
	}()

	return errChan
}

func startAPIServer(ctx context.Context, cfg *config.Config) error {
	var err error

	// init gpio
	err = rpio.Open()
	if err != nil {
		return err
	}
	defer rpio.Close()

	// set gpio pin
	relayPin := rpio.Pin(cfg.Server.RelayPin)
	// set pin mode output
	relayPin.Output()
	defer func() {
		relayPin.Low()
	}()

	// new middleware
	mw := middleware.Initialize(cfg.Server.Secret)

	svc := server.New(cfg)

	apiGroup := svc.Group("/api")
	apiGroup.Use(cc.PatchContext(mw.APIPanicCatch()))
	{
		rt.NewHTTP(relay.Initialize(relayPin), apiGroup, mw.Authorization())
	}

	svc.Start(ctx)

	return nil
}
