/*
        RegisterEmail - A webservice for selfhosted email servers to make it easy registering Emails (And optionally Enabling SSH)
        Copyright (C) 2024 Mike Nolan

        This program is free software: you can redistribute it and/or modify
        it under the terms of the GNU General Public License as published by
        the Free Software Foundation, either version 3 of the License, or
        (at your option) any later version.

        This program is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details.

        You should have received a copy of the GNU General Public License
        along with this program.  If not, see <https://www.gnu.org/licenses/>.
*/
using System.Diagnostics;
using System.Web;
using Newtonsoft.Json;
using Tesses.WebServer;

StaticServer server=new StaticServer("www");

RouteServer routeServer=new RouteServer(server);
routeServer.Add("/",async(ctx)=>{
    ctx.ParseBody();
    if(ctx.QueryParams.TryGetFirst("usernname",out var username) && !string.IsNullOrWhiteSpace(username) && ctx.QueryParams.TryGetFirst("password",out var password) && !string.IsNullOrWhiteSpace(password) && ctx.QueryParams.TryGetFirst("confirm",out var confirm) && !string.IsNullOrWhiteSpace(confirm) && ctx.QueryParams.TryGetFirst("fullname",out var fullname) && !string.IsNullOrWhiteSpace(fullname) && ctx.QueryParams.TryGetFirst("admin_username",out var admin_user) && !string.IsNullOrWhiteSpace(admin_user) && ctx.QueryParams.TryGetFirst("admin_password",out var admin_pass) && !string.IsNullOrWhiteSpace(admin_pass))
    {
        
        if(password==confirm)
        {
            if(username.Length>256)
            {
                await ctx.SendRedirectAsync("/failed?reason=Username+too+long");
                return;
            }
            bool can_login_ssh = ctx.QueryParams.TryGetFirst("ssh",out var _ssh) && _ssh == "on";
            bool has_sudo = ctx.QueryParams.TryGetFirst("sudo",out var _sudo) && _sudo == "on";
            
            object jsonObj = new {
                username,
                password,
                admin_user,
                admin_pass,
                fullname,
                can_login_ssh,
                has_sudo
            };
            string json = JsonConvert.SerializeObject(jsonObj);
            Process p = new Process();
            p.StartInfo.FileName = "/usr/local/bin/createemail";
            p.StartInfo.UseShellExecute=false;
            p.StartInfo.RedirectStandardInput =true;
            if(p.Start())
            {
                p.StandardInput.Write(json);
                p.StandardInput.Flush();
                if(!p.HasExited) p.WaitForExit();
                int statusCode=p.ExitCode;
                switch(statusCode)
                {
                    case 0:
                        await ctx.SendRedirectAsync($"/success?user={HttpUtility.UrlEncode(username)}");
                        break;
                    case 65:    
                        await ctx.SendRedirectAsync("/failed?reason=Unable+to+parse+JSON");
                        break;
                    case 77:
                        await ctx.SendRedirectAsync("/failed?reason=Admin+Access+Denied");
                        break;
                }
            }
        }
        else
        {
            await ctx.SendRedirectAsync("/failed?reason=Passwords+do+not+match");
        }
    }
    else await ctx.SendRedirectAsync("/failed?reason=You+did+not+fill+all+fields+out");
},"POST");
routeServer.Add("/failed",async(ctx)=>{
    ctx.QueryParams.TryGetFirst("reason",out var reason);
    await ctx.SendTextAsync(File.ReadAllText("www/fail.html").Replace("REASON",HttpUtility.HtmlEncode(reason)));
});
routeServer.Add("/success",async(ctx)=>{
    ctx.QueryParams.TryGetFirst("user",out var user); 
    await ctx.SendTextAsync(File.ReadAllText("www/success.html").Replace("EMAIL",HttpUtility.UrlEncode(user)));
});
routeServer.StartServer(2444);
