//Generated using MontoyaTech.Rest.Net
using System;
using System.Net;
using System.Net.Http;
using Newtonsoft.Json;

public class Client
{
    public string BaseUrl;

    public CookieContainer CookieContainer;

    public HttpMessageHandler MessageHandler;

    public HttpClient HttpClient;

    public TestApi Test;

    public AuthApi Auth;

    public StreamApi Stream;

    public Client(string baseUrl, HttpMessageHandler handler = null)
    {
        if (string.IsNullOrWhiteSpace(baseUrl))
            throw new ArgumentException("baseUrl must not be null or whitespace.");

        if (baseUrl.EndsWith('/'))
            baseUrl = baseUrl.Substring(0, baseUrl.Length - 1);

        this.BaseUrl = baseUrl;

        this.CookieContainer = new CookieContainer();

        if (handler == null)
        {
            handler = new HttpClientHandler()
            {
                AllowAutoRedirect = true,
                UseCookies = true,
                CookieContainer = this.CookieContainer,
                AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
            };
        }

        this.MessageHandler = handler;

        this.HttpClient = new HttpClient(handler);

        this.HttpClient.DefaultRequestHeaders.Add("Accept", "*/*");

        this.HttpClient.DefaultRequestHeaders.Add("Connection", "keep-alive");

        this.HttpClient.DefaultRequestHeaders.Add("Accept-Encoding", "identity");

        this.Test = new TestApi(this);

        this.Auth = new AuthApi(this);

        this.Stream = new StreamApi(this);
    }

    public class TestApi
    {
        public Client Client;

        public TestApi(Client client)
        {
            this.Client = client;
        }

        public string Status()
        {
            var message = new HttpRequestMessage(HttpMethod.Get, $"{this.Client.BaseUrl}/status");

            var response = this.Client.HttpClient.Send(message, HttpCompletionOption.ResponseHeadersRead);

            if (response.IsSuccessStatusCode)
            {
                var content = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();

                if (string.IsNullOrEmpty(content))
                    return default;

                return JsonConvert.DeserializeObject<string>(content);
            }
            else
            {
                throw new Exception("Unexpected Http Response StatusCode:" + response.StatusCode);
            }
        }

        public string Add(double a, double b)
        {
            var message = new HttpRequestMessage(HttpMethod.Post, $"{this.Client.BaseUrl}/add/{a}/{b}");

            var response = this.Client.HttpClient.Send(message, HttpCompletionOption.ResponseHeadersRead);

            if (response.IsSuccessStatusCode)
            {
                var content = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();

                if (string.IsNullOrEmpty(content))
                    return default;

                return JsonConvert.DeserializeObject<string>(content);
            }
            else
            {
                throw new Exception("Unexpected Http Response StatusCode:" + response.StatusCode);
            }
        }

        public string Compress()
        {
            var message = new HttpRequestMessage(HttpMethod.Get, $"{this.Client.BaseUrl}/compress");

            var response = this.Client.HttpClient.Send(message, HttpCompletionOption.ResponseHeadersRead);

            if (response.IsSuccessStatusCode)
            {
                var content = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();

                if (string.IsNullOrEmpty(content))
                    return default;

                return JsonConvert.DeserializeObject<string>(content);
            }
            else
            {
                throw new Exception("Unexpected Http Response StatusCode:" + response.StatusCode);
            }
        }

        public string CompressFile()
        {
            var message = new HttpRequestMessage(HttpMethod.Get, $"{this.Client.BaseUrl}/file/compress");

            var response = this.Client.HttpClient.Send(message, HttpCompletionOption.ResponseHeadersRead);

            if (response.IsSuccessStatusCode)
            {
                var content = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();

                if (string.IsNullOrEmpty(content))
                    return default;

                return JsonConvert.DeserializeObject<string>(content);
            }
            else
            {
                throw new Exception("Unexpected Http Response StatusCode:" + response.StatusCode);
            }
        }
    }

    public class AuthApi
    {
        public Client Client;

        public AuthApi(Client client)
        {
            this.Client = client;
        }

        public bool UserExists(string name)
        {
            var message = new HttpRequestMessage(HttpMethod.Get, $"{this.Client.BaseUrl}/auth/{name}");

            var response = this.Client.HttpClient.Send(message, HttpCompletionOption.ResponseHeadersRead);

            if (response.IsSuccessStatusCode)
            {
                var content = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();

                if (string.IsNullOrEmpty(content))
                    return default;

                return bool.Parse(content);
            }
            else
            {
                throw new Exception("Unexpected Http Response StatusCode:" + response.StatusCode);
            }
        }

        public void Signup(UserDto request)
        {
            var message = new HttpRequestMessage(HttpMethod.Post, $"{this.Client.BaseUrl}/auth/signup");

            message.Content = new StringContent(JsonConvert.SerializeObject(request));

            var response = this.Client.HttpClient.Send(message, HttpCompletionOption.ResponseHeadersRead);

            if (!response.IsSuccessStatusCode)
                throw new Exception("Unexpected Http Response StatusCode:" + response.StatusCode);
        }

        public UserDto Get()
        {
            var message = new HttpRequestMessage(HttpMethod.Get, $"{this.Client.BaseUrl}/auth");

            var response = this.Client.HttpClient.Send(message, HttpCompletionOption.ResponseHeadersRead);

            if (response.IsSuccessStatusCode)
            {
                var content = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();

                if (string.IsNullOrEmpty(content))
                    return default;

                return JsonConvert.DeserializeObject<UserDto>(content);
            }
            else
            {
                throw new Exception("Unexpected Http Response StatusCode:" + response.StatusCode);
            }
        }

        public UserRole GetRole()
        {
            var message = new HttpRequestMessage(HttpMethod.Get, $"{this.Client.BaseUrl}/auth/role");

            var response = this.Client.HttpClient.Send(message, HttpCompletionOption.ResponseHeadersRead);

            if (response.IsSuccessStatusCode)
            {
                var content = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();

                if (string.IsNullOrEmpty(content))
                    return default;

                return JsonConvert.DeserializeObject<UserRole>(content);
            }
            else
            {
                throw new Exception("Unexpected Http Response StatusCode:" + response.StatusCode);
            }
        }
    }

    public class StreamApi
    {
        public Client Client;

        public StreamApi(Client client)
        {
            this.Client = client;
        }

        public void Upload(System.IO.MemoryStream request)
        {
            var message = new HttpRequestMessage(HttpMethod.Post, $"{this.Client.BaseUrl}/upload");

            request.Seek(0, System.IO.SeekOrigin.Begin);

            message.Content = new StreamContent(request);

            var response = this.Client.HttpClient.Send(message, HttpCompletionOption.ResponseHeadersRead);

            if (!response.IsSuccessStatusCode)
                throw new Exception("Unexpected Http Response StatusCode:" + response.StatusCode);
        }

        public System.IO.MemoryStream Download()
        {
            var message = new HttpRequestMessage(HttpMethod.Get, $"{this.Client.BaseUrl}/download");

            var response = this.Client.HttpClient.Send(message, HttpCompletionOption.ResponseHeadersRead);

            if (response.IsSuccessStatusCode)
            {
                var stream = new System.IO.MemoryStream();

                response.Content.CopyToAsync(stream).GetAwaiter().GetResult();

                return stream;
            }
            else
            {
                throw new Exception("Unexpected Http Response StatusCode:" + response.StatusCode);
            }
        }
    }

    public class IncludedType
    {
        public int Test;

        public IncludedType() { }

        public IncludedType(IncludedType instance)
        {
            this.Test = instance.Test;
        }

        public IncludedType(int Test = 0)
        {
            this.Test = Test;
        }
    }

    public class UserDto : BaseUser
    {
        public System.PlatformID MachineType;

        public string Name;

        public System.Collections.Generic.List<string> List;

        public System.String[] Array;

        public ulong Property { get; set; }

        public UserDto() { }

        public UserDto(UserDto instance)
        {
            this.MachineType = instance.MachineType;
            this.Name = instance.Name;
            this.List = instance.List;
            this.Array = instance.Array;
            this.Property = instance.Property;
        }

        public UserDto(System.PlatformID MachineType = 0, string Name = null, System.Collections.Generic.List<string> List = null, System.String[] Array = null, ulong Property = 0)
        {
            this.MachineType = MachineType;
            this.Name = Name;
            this.List = List;
            this.Array = Array;
            this.Property = Property;
        }
    }

    public class BaseUser
    {
        public string Id;

        public char FirstInitial;

        public System.Collections.Generic.List<Permission> Permissions;

        public UserRole Role { get; set; }

        public BaseUser() { }

        public BaseUser(BaseUser instance)
        {
            this.Id = instance.Id;
            this.FirstInitial = instance.FirstInitial;
            this.Permissions = instance.Permissions;
            this.Role = instance.Role;
        }

        public BaseUser(string Id = null, char FirstInitial = '\0', System.Collections.Generic.List<Permission> Permissions = null, UserRole Role = 0)
        {
            this.Id = Id;
            this.FirstInitial = FirstInitial;
            this.Permissions = Permissions;
            this.Role = Role;
        }

        public class Permission
        {
            public string Name;

            public Types Type;

            public Permission() { }

            public Permission(Permission instance)
            {
                this.Name = instance.Name;
                this.Type = instance.Type;
            }

            public Permission(string Name = null, Types Type = 0)
            {
                this.Name = Name;
                this.Type = Type;
            }

            public enum Types : int
            {
                Read = 0,

                Write = 1,
            }
        }
    }

    public enum UserRole : byte
    {
        Unknown = 0,

        Admin = 2,

        User = 1,
    }
}