@startuml
top to bottom direction
skinparam linetype ortho

node PilotNode as "Pilot Node" {
    database DataStore as "Data Store"

    component EmissaryServer as "Emissary Server" {

        component SpecificationRegistry as "Specification Registry" {
            component UCISpecification as "UCI Spec"
            component MDNSSpecification as "mDNS Spec"
            component AppSpecification as "App Spec"
            component ProxySpecification as "Proxy Spec"
            component SysUpgradeSpecification as "SysUpgrade Spec"
        }

        component HTTPHandler as "HTTP Handler"

        HTTPHandler .down.> SpecificationRegistry: validates agents data with

        HTTPHandler .right.> DataStore: saves agent data in
    }
}

node OperatorNode as "Operator Node" {
    component EmissaryClient as "Emissary Client"

    EmissaryClient -left-> HTTPHandler: administrates
}

node OpenWRTNode as "OpenWRT Node" {
    component EmissaryAgent as "Emissary Agent" {

        component StateManager as "State Manager"

        StateManager --up-> HTTPHandler: fetches agent ^*specs from

        component UCIController as "UCI Controller"

        UCIController .up.> StateManager: reconciles with

        component SysUpgradeController as "SysUpgrade Controller"

        SysUpgradeController .up.> StateManager: reconciles with
    
        component ProxyController as "Proxy Controller"

        ProxyController .up.> StateManager: reconciles with

        component MDNSController as "mDNS Controller"

        MDNSController .up.> StateManager: reconciles with

        component AppController as "App Controller"

        AppController .up.> StateManager: reconciles with
    }
}