﻿// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using System.Web.Http.SelfHost;
using System.Web.Http;
using log4net;
using HypervResource;

namespace CloudStack.Plugin.AgentShell
{
    public partial class AgentService : ServiceBase
    {
        [System.Runtime.InteropServices.DllImport("kernel32.dll", SetLastError = true)]
        static extern bool AllocConsole();

        [System.Runtime.InteropServices.DllImport("kernel32.dll", SetLastError = true)]
        static extern bool FreeConsole();

        HttpSelfHostServer server;

        private static ILog logger = LogManager.GetLogger(typeof(AgentService));

        public AgentService()
        {
            logger.Info("Starting CloudStack agent");
            InitializeComponent();

            UriBuilder baseUri = new UriBuilder("http", AgentSettings.Default.private_ip_address, AgentSettings.Default.port);

            var config = new HttpSelfHostConfiguration(baseUri.Uri);

           // Allow ActionName to be applied to methods in ApiController, which allows it to serve multiple POST URLs
            config.Routes.MapHttpRoute(
                  "API Default", "api/{controller}/{action}",
                  new { action = RouteParameter.Optional }
                    );

            // Load controller assemblies that we want to config to route to.
            ConfigServerResource();
            AssertControllerAssemblyAvailable(config, typeof(HypervResourceController), "Cannot load Controller of type" + typeof(HypervResourceController));

            server = new HttpSelfHostServer(config);
        }

        public static void ConfigServerResource()
        {
            // For simplicity, ServerResource config and settings file are tightly coupled.
            // An alternative is to pass a dictionary to the server resource and let it find 
            // required settings.  In contrast, the approach below is strongly typed and makes
            // use of VisualStudio settings designer.  The designer allows us to avoid
            // accessing config using their key strings.
            HypervResourceControllerConfig rsrcCnf = new HypervResourceControllerConfig();
            rsrcCnf.PrivateIpAddress = AgentSettings.Default.private_ip_address;
            rsrcCnf.GatewayIpAddress = AgentSettings.Default.gateway_ip_address;
            rsrcCnf.RootDeviceReservedSpaceBytes = AgentSettings.Default.RootDeviceReservedSpaceBytes;
            rsrcCnf.RootDeviceName = AgentSettings.Default.RootDeviceName;
            rsrcCnf.ParentPartitionMinMemoryMb = AgentSettings.Default.dom0MinMemory;
            rsrcCnf.LocalSecondaryStoragePath = AgentSettings.Default.local_secondary_storage_path;
            rsrcCnf.systemVmIso = null;

            // Side effect:  loads the assembly containing HypervResourceController, which
            // allows HttpSelfHostServer to route requests to the controller.
            HypervResourceController.Configure(rsrcCnf);

        }

        // TODO:  update to examine not the assembly resolver, but the list of available controllers themselves!
        private static bool AssertControllerAssemblyAvailable(HttpSelfHostConfiguration config, Type controllerType, string errorMessage)
        {
            var assemblies = config.Services.GetAssembliesResolver().GetAssemblies();
            foreach (var assembly in assemblies)
            {
                string name = assembly.GetName().Name;
                if (controllerType.Assembly.GetName().Name.Equals(name))
                {
                    logger.DebugFormat("Controller {0} is available", controllerType.Name);
                    return true;
                }
            }

            logger.Error(errorMessage);
            throw new AgentShellException(errorMessage);
        }

        protected override void OnStart(string[] args)
        {
            server.OpenAsync().Wait();
        }

        protected override void OnStop()
        {
            server.CloseAsync().Wait();
        }

        internal void RunConsole(string[] args)
        {
            OnStart(args);

            AllocConsole();

            Console.WriteLine("Service running ... press <ENTER> to stop");

            Console.ReadLine();

            FreeConsole();

            OnStop();
        }
    }
}
