// Shows how to configure the OPC UA .NET stack and SDK using its configuration file (XML). For more information, see
// https://kb.opclabs.com/OPC_UA_.NET_SDK_Configuration .
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client and subscriber examples in C# on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-CSharp .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.
using System;
using OpcLabs.BaseLib.Instrumentation;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.Engine;
using OpcLabs.EasyOpc.UA.OperationModel;
namespace UANetSdkConfiguration
{
    class Program
    {
        static void Main()
        {
            // Set the source of OPC UA .NET SDK configuration to the "App.config" file only. In "old-style" Visual Studio
            // projects (for .NET Framework only), during the build, Visual Studio copies the "App.config" file from the
            // project to the output directory, and renames it to match the name of the executable. In this example, the
            // "App.config" from the project becomes "UANetSdkConfiguration.exe.config" in the build output directory. The
            // runtime looks for this file by appending ".config" to the name of the currently running executable.
            //
            // In "new-style" Visual Studio projects (mainly for .NET Core/.NET 5+), this automatic mechanism is not
            // present. To get around it, simply include a properly named "App.config" file (in our case, it is
            // "UANetSdkConfiguration.dll.config") in the project's root directory, and set "Copy to Output Directory" in
            // its Properties to either "Copy always" or "Copy if newer". Notice the ".dll.config" file extension used
            // under .NET Core/.NET 5+, as opposed to ".exe.config" under .NET Framework.
            // 
            // The "App.config" mechanism is a standard configuration mechanism in .NET Framework. In our case, the
            // "App.config" contains a references to *another* XML configuration file, whose format is specific to the OPC
            // UA .NET SDK. This example calls this file "MyApplication.Config.xml", but it can have any name, as long as it
            // matches the information provided in the (properly renamed) "App.config".
            //
            // The "MyApplication.Config.xml" file in this example specifies somewhat lower value for the MaxMessageSize
            // transport quota than the default.
            //
            // If the "App.config" file does not specify the file path of the OPC UA .NET SDK configuration, the component
            // tries to load it from a default file, residing in the same directory as the application's executable
            // assembly, and with the same name, but with a file extension ".Config.xml". This means that for this project,
            // it would be named UANetSdkConfiguration.Config.xml.
            EasyUAClient.SharedParameters.EngineParameters.ConfigurationSources = UAConfigurationSources.AppConfig;
            // Hook static events.
            // Uncomment the statement below for troubleshooting.
            //EasyUAClient.LogEntry += EasyUAClientOnLogEntry;
            // Perform some OPC operations.
            UAEndpointDescriptor endpointDescriptor =
                "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer";
            // or "http://opcua.demo-this.com:51211/UA/SampleServer" (currently not supported)
            // or "https://opcua.demo-this.com:51212/UA/SampleServer/"
            // Instantiate the client object
            var client = new EasyUAClient();
            Console.WriteLine("Obtaining value of a node...");
            try
            {
                object value = client.ReadValue(endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10853");
                // Display results
                Console.WriteLine("value: {0}", value);
            }
            catch (UAException uaException)
            {
                Console.WriteLine("*** Failure: {0}", uaException.GetBaseException().Message);
            }
            Console.WriteLine();
            Console.WriteLine("Press Enter to continue...");
            Console.ReadLine();
        }
        // Event handler for the LogEntry event.
        // Display the loggable entries related to UA .NET SDK configuration.
        private static void EasyUAClientOnLogEntry(object sender, LogEntryEventArgs logEntryEventArgs)
        {
            if ((130 <= logEntryEventArgs.EventId) && (logEntryEventArgs.EventId <= 139))
                Console.WriteLine(logEntryEventArgs);
        }
    }
}