using System;
using System.Runtime.InteropServices;
using System.Text;

namespace Unosquare.RaspberryIO.Abstractions.Native {
  /// <summary>
  /// Provides standard 'libc' calls using platform-invoke.
  /// </summary>
  public static class Standard {
    internal const String LibCLibrary = "libc";

    #region LibC Calls

    /// <summary>
    /// Strerrors the specified error.
    /// </summary>
    /// <param name="error">The error.</param>
    /// <returns>The error string.</returns>
    public static String Strerror(Int32 error) {
      if(Type.GetType("Mono.Runtime") == null) {
        return Marshal.PtrToStringAnsi(StrError(error));
      }

      try {
        StringBuilder buffer = new StringBuilder(256);
        Int32 result = Strerror(error, buffer, (UInt64)buffer.Capacity);
        return (result != -1) ? buffer.ToString() : null;
      } catch(Exception) {
        return null;
      }
    }

    [DllImport(LibCLibrary, EntryPoint = "strerror", SetLastError = true)]
    private static extern IntPtr StrError(Int32 errnum);

    [DllImport("MonoPosixHelper", EntryPoint = "Mono_Posix_Syscall_strerror_r", SetLastError = true)]
    private static extern Int32 Strerror(Int32 error, [Out] StringBuilder buffer, UInt64 length);

    #endregion
  }
}