// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

/**
 @page libyang libkea-yang - Kea YANG Utilities Library

The libkea-yang library was developed to handle base YANG operations,
such are retrieving YANG schema and configuration and translating
data between YANG syntax and JSON that is understandable by Kea.

@section yangTranslator Translator between YANG and JSON

An essential concept is the idea of translator. It is a primitive that is able
to convert certain data structure between YANG and JSON. It is envisaged
that more complex translators will use other translators to handle more
complex data structures. For details, see @ref isc::yang::TranslatorBasic.

Note that although the initial focus is on translation from YANG to JSON (so
Kea can retrieve its configuration), the opposite translation direction -
from JSON to YANG - is also very useful, for at least two reasons. First,
in many cases we can use it in tests to check that conversion back and forth
doesn't lose anything: yang = toYang(toJson(yang)). Second, YANG models
cover two major types of data: configuration and run-time state. While
we're initially focusing on getting the configuration, the run-time state
is something that Kea is expected to provide. Kea uses JSON internally in many
places and that data will have to be exported in YANG format.

All translators take a Session pointer (a structure provided by Sysrepo that
is responsible for maintaining a connection) in constructors and derive from
the basic / base class and recursively of translators for embedded parts.

@c isc::yang::TranslatorBasic provides some methods:
 - getItem() gets and translates basic value from YANG to JSON
 - getItems() gets and translates a leaf-list from YANG to JSON
   (for a list please use an iterator)
 - setItem() translates and sets a basic value from JSON to YANG
 - delItem() deletes a value
 - getIter() gets an iterator over a YANG list
 - getNext() returns the xpath of the next item

@section yangTranslatorPool Pool translator

@c isc::yang::TranslatorPool is the standard example of a translator
for a structured value. Its constructor takes a model name: the code
implements some variants to accommodate the model with shared code
moved into a common private routine. When called with an unsupported
model, generic methods of all structure translators throw
@c isc::NotImplemented.

@c isc::yang::TranslatorPools deals with a list of pools. The getPools
method iterates over the list in both ways. Look at examples in unit
tests to understand how can be filled.

Note pools show two shortcomings in IETF models:
 - option sets make to track changes nearly impossible: the only easy
  code is to translate the whole configuration.
 - prefix and start - end forms of pool ranges are both mandatory.
  (reported to authors' so should be fixed in the next version).

All structure translators depend on @c isc::yang::TranslatorBasic and
some of them depend on other structures, for instance
@c isc::yang::TranslatorPool depends on
@c isc::yang::TranslatorOptionDataList which itself as all list translators
depends on the corresponding list item translator
@c isc::yang::TranslatorOptionData. This multiple inheritance forms
a graph with the basic and the configuration translators at the two ends.
Multiple inheritance and its "diamond" issue are handled by C++ with
the "virtual" inheritance: depending classes must be virtually inherited
and explicitly constructed.

@section yangTranslatorSubnet Subnet translator

The new thing here is the use of adaptors to move timers from subnets
to pools and back.

@section yangAdaptor Adapting JSON configuration

Adaptors are tools which adapts JSON complete or partial configuration
before translation to YANG to ease this translation or after translation
from YANG to follow the Kea syntax, for instance by adding static
components which are not in the model.

Methods provided by adaptors are class methods (i.e. declared static).
Specific adaptors can be derived from the isc::yang::Adaptor base class.

There are a few basic adaptors and per structure adaptors. The second
category of adaptors are divided into:
 - from JSON to YANG adaptors or pre-processing which adapt a JSON
  configuration to make it acceptable by a from JSON to YANG (setXXX)
  translators. For a Kea model this kind of adaptors fill some required
  but missing fields, or only transform a configuration into a canonical
  form. Note for a Kea model and a configuration taken from config-get
  or config-write it likely does nearly nothing but the code must
  handle any hand written configuration so these adaptors are always
  applied.

 - from YANG to JSON adaptors or post-processing which adapt translated
  YANG configuration (by getXXX) to make it acceptable by a Kea server.
  By definition they are not defined for Kea models.

@section unitTestsSysrepo Running unit-tests with Sysrepo

To run YANG/NETCONF/Sysrepo tests you obviously need to compile Kea with
Sysrepo support:

@verbatim
./configure --with-sysrepo
@endverbatim

For details, see Section 20 "YANG/NETCONF support" in the Kea User's Guide.

You also need to install YANG schemas, so the unit-tests are able to
retrieve, add, update and generally interact with the sysrepo information.
There are several production Kea models (src/share/yang/modules/kea*.yang)
and one test specific model (src/share/yang/modules/keatest-module*.yang)
which is only required if you want to run Kea unit tests, i.e. it is not
used in production.

To install the test module, issue the following command:

@verbatim
sudo sysrepoctl --install --yang=src/share/yang/modules/keatest-module*.yang
@endverbatim

To verify that you have the schemas installed, do this:
@verbatim
sysrepoctl -l
@endverbatim
Make sure that keatest-module and other necessary modules are on the list.

Note as DHCP modules are still being developed it can be useful to
deinstall them before reinstalling a more recent version:
@verbatim
sudo sysrepoctl --uninstall --module=<module-name>
@endverbatim

Tests use these modules you can find in src/share/yang/modules in addition
of keatest-module:
 - ietf-dhcpv6-server
 - kea-ctrl-agent
 - kea-dhcp-ddns
 - kea-dhcp4-server
 - kea-dhcp6-server

Those models depend on the following modules:
 - ietf-inet-types
 - ietf-yang-types
 - ietf-interfaces
 - kea-types
 - kea-logging
 - kea-dhcp-types

Those modules are extracted from the IETF DHCPv6 YANG draft too:
 - ietf-dhcpv6-client
 - ietf-dhcpv6-relay

All are available in the src/share/yang/modules directory using the
<module-name>[@<revision>].yang syntax for file names.
src/share/yang/modules/utils provides a few utilities for developers:
 - check-revisions.sh which verifies if the revision in the file name
  and in the file content matches
 - check-hashes.sh which detects updates in the file content without
  a revision change using the SHA-256 hash of the to YIN translation.
 - gen-revisions.sh which produces the module / revision table of
  the yang_revisions.h header file.

Finally, sysrepod daemon must run be running (as root):
@verbatim
sudo sysrepod
@endverbatim

You can run this tool:

@verbatim
src/lib/yang/pretests/sysrepo_setup_tests
@endverbatim

to verify that your environment is ready. If there is anything
wrong, it will enumerate the problems and will suggest how to solve
them.

*/
