using NIDAQmx.DAQmxEnum;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace NIDAQmx
{
    public class SystemInfo : DAQmxBase
    {
        internal SystemInfo(DAQmxSession session) : base(session)
        {
            MajorVersion = GetMajorVersion();
            MinorVersion = GetMinorVersion();
            UpdateVersion = GetUpdateVersion();
            DevNames = GetSysDevNames();
            Scales =GetSysScales();
            GlobalChans = GetSysGlobalChans();
            Tasks = GetSysTasks();
            List<string> s = new List<string>();
            s.Add("OnboardClock");
            s.AddRange(DevNames.SelectMany(x =>
            {
                byte[] bytes = new byte[10240];
                _Session.CheckResult(_Session.GetDelegate<Internal.Internal.DAQmxGetDevTerminals>()(x, ref bytes[0], (uint)bytes.Length));
                return Encoding.UTF8.GetString(bytes).Split(",").Select(x => x.Trim('\0')).Where(x => !String.IsNullOrEmpty(x) && x.IndexOf("None")<0);
            }));
            SampleClocks = s.ToArray();
        }
        private string[] GetSysScales()
        {
            Byte[] bytes = new Byte[4096];
            var result = _Session.GetDelegate<Internal.Internal.DAQmxGetSysScales>()(ref bytes[0], (uint)bytes.Length);
            _Session.CheckResult(result);
            return Encoding.UTF8.GetString(bytes).Split(",").Select(x => x.Trim('\0')).Where(x => !String.IsNullOrEmpty(x)).ToArray(); ;
        }
        private string[] GetSysTasks()
        {
            Byte[] bytes = new Byte[4096];
            var result = _Session.GetDelegate<Internal.Internal.DAQmxGetSysTasks>()(ref bytes[0], (uint)bytes.Length);
            _Session.CheckResult(result);
            return Encoding.UTF8.GetString(bytes).Split(",").Select(x => x.Trim('\0')).Where(x => !String.IsNullOrEmpty(x)).ToArray(); ;
        }
        private string[] GetSysDevNames()
        {
            Byte[] bytes = new Byte[4096];
            var result = _Session.GetDelegate<Internal.Internal.DAQmxGetSysDevNames>()(ref bytes[0], (uint)bytes.Length);
            _Session.CheckResult(result);
            return Encoding.UTF8.GetString(bytes).Split(",").Select(x => x.Trim('\0')).Where(x => !String.IsNullOrEmpty(x)).ToArray();;
        }
        private string[] GetSysGlobalChans()
        {
            Byte[] bytes = new Byte[4096];
            var result = _Session.GetDelegate<Internal.Internal.DAQmxGetSysGlobalChans>()(ref bytes[0], (uint)bytes.Length);
            _Session.CheckResult(result);
            return Encoding.UTF8.GetString(bytes).Split(",").Select(x => x.Trim('\0')).Where(x => !String.IsNullOrEmpty(x)).ToArray(); ;
        }
        private uint GetMajorVersion()
        {
            uint val = 0;
            _Session.CheckResult(_Session.GetDelegate<Internal.Internal.DAQmxGetSysNIDAQMajorVersion>()(ref val));
            return val;
        }
        private uint GetMinorVersion()
        {
            uint val = 0;
            _Session.CheckResult(_Session.GetDelegate<Internal.Internal.DAQmxGetSysNIDAQMinorVersion>()(ref val));
            return val;
        }
        private uint GetUpdateVersion()
        {
            uint val = 0;
            _Session.CheckResult(_Session.GetDelegate<Internal.Internal.DAQmxGetSysNIDAQUpdateVersion>()(ref val));
            return val;
        }
        public string[] SampleClocks { get; }
        public string[] GlobalChans { get; }

        public string[] Scales { get; }
        public string[] Tasks { get; }
        public string[] DevNames { get; }
        public uint MajorVersion { get; }
        public uint MinorVersion { get; }
        public uint UpdateVersion { get; }
    }
}
