// POST: api/Cameras/Deactivate/1
        public async Task <IHttpActionResult> Deactivate(int id)
        {
            using (var db = new VideoAnalyticContext())
            {
                Camera camera = db.Cameras.Find(id);
                if (camera == null)
                {
                    return(NotFound());
                }

                var        deviceId = camera.HostingDevice;
                EdgeDevice device   = db.EdgeDevices.Find(deviceId);
                if (device == null)
                {
                    return(NotFound());
                }

                var configStr = device.Configurations;
                if (string.IsNullOrEmpty(configStr))
                {
                    return(InternalServerError());
                }

                var moduleName   = camera.Name;
                var resultConfig = await IoTEdgeManager.DeleteModuleOnDeviceAsync(moduleName, device.Name, camera.Pipeline, JObject.Parse(configStr));

                device.Configurations = resultConfig;
                camera.Status         = "NotActive";

                db.SaveChanges();

                return(Ok());
            }
        }
        public async Task<HttpResponseMessage> AddEdgeDevice(JObject body)
        {
            try
            {
                var deviceName = body?.GetValue("deviceName")?.Value<string>();
                var deviceDescription = body?.GetValue("deviceDescription")?.Value<string>() ?? "";
                var osType = body?.GetValue("osType")?.Value<string>();
                var capacity = body?.GetValue("capacity")?.Value<int>() ?? 0;

                if (string.IsNullOrEmpty(deviceName) || string.IsNullOrEmpty(osType))
                {
                    return Request.CreateErrorResponse(HttpStatusCode.BadRequest, "Invalid body. deviceName,osType is required");
                }


                using (var db = new VideoAnalyticContext())
                {
                    var device = await db.EdgeDevices.SingleOrDefaultAsync(d => d.Name.Equals(deviceName));
                    if (device != null)
                    {
                        return Request.CreateErrorResponse(HttpStatusCode.Conflict, $"Device with name: {deviceName} already exits.");
                    }

                    var connectString = await IoTEdgeManager.AddDeviceAsync(deviceName);

                    if (string.IsNullOrEmpty(connectString))
                    {
                        return Request.CreateErrorResponse(HttpStatusCode.NotAcceptable, $"Create Device with name: {deviceName} failed!.");
                    }

                    EdgeDevice edgeDevice = new EdgeDevice()
                    {
                        Name = deviceName,
                        Description = deviceDescription,
                        OSType = osType,
                        Capacity = capacity,
                        ConnectString = connectString,
                        Status = EdgeDeviceStatus.Create.ToString(),
                        CreatedOn = DateTime.UtcNow
                    };

                    db.EdgeDevices.Add(edgeDevice);
                    db.SaveChanges();

                    return Request.CreateResponse(HttpStatusCode.OK, edgeDevice);
                }

            }
            catch (Exception e)
            {
                LogUtil.LogException(e);
                return Request.CreateResponse(HttpStatusCode.InternalServerError, e.Message);
            }

        }
        // GET: api/EdgeDevices/CheckEdgeDeviceStatus
        public async Task<IHttpActionResult> CheckEdgeDeviceStatus()
        {
            using (var db = new VideoAnalyticContext())
            {
                var edgeDevices = db.EdgeDevices.ToList();
                foreach (var device in edgeDevices)
                {
                    var isConnected = await IoTEdgeManager.CheckDeviceStatesAsync(device.Name);
                    if (isConnected)
                    {
                        device.Status = EdgeDeviceStatus.Connected.ToString();
                    }
                    else
                    {
                        device.Status = EdgeDeviceStatus.Disconnected.ToString();
                    }
                    db.SaveChanges();
                }

                return Ok();
            }
        }
        // POST: api/Cameras/Activate/1
        public async Task <IHttpActionResult> Activate(int id)
        {
            using (var db = new VideoAnalyticContext())
            {
                Camera camera = db.Cameras.Find(id);
                if (camera == null)
                {
                    return(NotFound());
                }

                var        deviceId = camera.HostingDevice;
                EdgeDevice device   = db.EdgeDevices.Find(deviceId);
                if (device == null)
                {
                    return(NotFound());
                }

                var configStr = device.Configurations;
                if (string.IsNullOrEmpty(configStr))
                {
                    configStr = File.ReadAllText($"{WebApiConfig.DataPath}/moduleTemplate/default.json");
                }

                var properties = new JObject
                {
                    { "RTSP", camera.Stream }
                };

                var moduleName   = camera.Name;
                var resultConfig = await IoTEdgeManager.AddModuleOnDeviceAsync(moduleName, device.Name, camera.Pipeline, properties, JObject.Parse(configStr));

                device.Configurations = resultConfig;
                camera.Status         = "Active";
                db.SaveChanges();

                return(Ok());
            }
        }
        public async Task<IHttpActionResult> DeleteEdgeDevice(int id)
        {
            using (var db = new VideoAnalyticContext())
            {
                EdgeDevice edgeDevice = await db.EdgeDevices.SingleOrDefaultAsync(d => d.Id == id);
                if (edgeDevice == null)
                {
                    return NotFound();
                }

                var cameras = await db.Cameras.Where(d => d.HostingDevice == edgeDevice.Id).ToListAsync();
                if (cameras.Count > 0)
                {
                    return Content(HttpStatusCode.Forbidden, $"Cannot delete Edge Device {id}, since there are {cameras.Count} cameras connected. Delete all cameras connected to this device first. ");
                }

                await IoTEdgeManager.DeleteDeviceAsync(edgeDevice.Name);
                db.EdgeDevices.Remove(edgeDevice);
                db.SaveChanges();

                return Ok(edgeDevice);
            }
        }