@startuml

class Moka <<facade>> {
  start(Module) : MokaServer
  stop(MokaServer)
  replace(Moka, ...)
  export(Moka, Function)
  load(Moka)
  history(Moka) : [{Fun, Args, Result}]
}

class MokaServer {

  start(Module)
  stop()
  replace_remote_call(Module, Function, Fun)
  replace_local_call(Function, Fun)
  export(Function)
  load()
  history() : [{Fun, Args, Result}]
}

class ModUtils <<library>> {
  get_abstract_code(Module)
  replace_remote_call(Abstact, CallTo = {Module, Function}, Fun)
  replace_local_call(Abstact, Function, Fun)
  export(Abstact, Function)
  restore(Module)
}

class AbsCode <<data>> {
  module
  source
}

class CallHandler {
  - behaviour: fun

  start(Fun)
  get_response(Args)
}

class FunWorker  <<temporary>> {
  eval(Fun)
}

class History {
  - calls : [{Function, Args, Result}]

  add_call(Function, Args, Result)
  get_calls()
}

note as M3
  Any representation of
  erlang source code
end note
M3 .. AbsCode

class MainSup <<supervisor>> {
  start()
  start_new_moka()
}
class MokaSup <<supervisor>> {
  start()
  start_call_handler()
}

Moka ..> MainSup
Moka ..> MokaServer
Moka ..> History

MokaServer *--> "1" AbsCode
MokaServer  ..>     MokaSup
MokaServer  ..>     ModUtils
ModUtils    ..>     AbsCode

MainSup  ..> MokaSup

CallHandler *--> "*" FunWorker

FunWorker ..> History

AbsCode ..> CallHandler

@enduml
