using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Security.Authentication; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using MongoDB.Bson; using Mqtt.Client.AspNetCore.Services; using MyCore.Interfaces.DTO; using MyCore.Interfaces.Models; using MyCore.Service.Services; using MyCore.Services; using MyCore.Services.Devices; using MyCore.Services.MyControlPanel; namespace MyCore.Service.Controllers { [Authorize] // TODO Add ROLES (Roles = "Admin") [Route("api/group")] [ApiController] public class GroupController : ControllerBase { private UserDatabaseService _UserDatabaseService; private GroupDatabaseService _GroupDatabaseService; private DeviceDatabaseService _DeviceDatabaseService; private ProviderDatabaseService _ProviderDatabaseService; private readonly IMqttClientService _mqttClientService; //private readonly IMqttOnlineClientService _mqttOnlineClientService; public GroupController(UserDatabaseService userDatabaseService, GroupDatabaseService groupDatabaseService, DeviceDatabaseService deviceDatabaseService, ProviderDatabaseService providerDatabaseService, MqttClientServiceProvider provider)//, MqttClientOnlineServiceProvider onlineProvider) { this._UserDatabaseService = userDatabaseService; this._GroupDatabaseService = groupDatabaseService; this._DeviceDatabaseService = deviceDatabaseService; this._ProviderDatabaseService = providerDatabaseService; this._mqttClientService = provider.MqttClientService; //this._mqttOnlineClientService = onlineProvider.MqttOnlineClientService; } /// /// Get all groups for the specified user /// /// Id of user [ProducesResponseType(typeof(List), 200)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 500)] [HttpGet("{userId}")] public ObjectResult GetAll(string userId) { try { if (userId == null) throw new ArgumentNullException("Incorrect parameters"); List Groups = _GroupDatabaseService.GetAll(userId); List groupsSummaryDTO = Groups.Select(d => d.ToSummaryDTO()).ToList(); return new OkObjectResult(groupsSummaryDTO); } catch (ArgumentNullException ex) { return new BadRequestObjectResult(ex.Message) { }; } catch (Exception ex) { return new ObjectResult(ex.Message) { StatusCode = 500 }; } } /// /// Get detail info of a specified group /// /// groupid [ProducesResponseType(typeof(GroupDetailDTO), 200)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] [HttpGet("detail/{groupId}")] public ObjectResult GetDetail(string groupId) { try { if (groupId == null) throw new ArgumentNullException("Incorrect parameters"); Group group = _GroupDatabaseService.GetById(groupId); if (group == null) throw new KeyNotFoundException("Group not found"); List devices = _DeviceDatabaseService.GetByLocation(group.UserId, groupId); return new OkObjectResult(group.ToDTO(devices.Select(d => d.ToDTO()).ToList())); } catch (ArgumentNullException ex) { return new BadRequestObjectResult(ex.Message) {}; } catch (KeyNotFoundException ex) { return new NotFoundObjectResult(ex.Message) {}; } catch (Exception ex) { return new ObjectResult(ex.Message) { StatusCode = 500 }; } } /// /// Get list of group from a type /// /// user Id /// group type [ProducesResponseType(typeof(List), 200)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 500)] [HttpGet("{userId}/type/{type}")] public ObjectResult GetGroupsByType(string userId, string type) // Change string type to enum ? Lights etc ? { try { if (userId == null || type == null) throw new ArgumentNullException("Incorrect parameters"); List groups = _GroupDatabaseService.GetByType(userId, type); return new OkObjectResult(groups.Select(d => d.ToSummaryDTO())); } catch (ArgumentNullException ex) { return new BadRequestObjectResult(ex.Message) {}; } catch (Exception ex) { return new ObjectResult(ex.Message) { StatusCode = 500 }; } } /// /// Get all zigbee2Mqtt groups /// /// User Id [ProducesResponseType(typeof(List), 200)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] [HttpGet("zigbee2Mqtt/{userId}")] public ObjectResult GetGroupsFromZigbee2Mqtt(string userId) { try { if (userId == null) throw new ArgumentNullException("Incorrect parameters"); if (!UserService.IsExist(_UserDatabaseService, userId)) throw new KeyNotFoundException("User not found"); // GET ALL LOCAL GROUPS var groups = MqttClientService.groups; // Be carefull, we only got the exact result after each connection return new OkObjectResult(groups); } catch (ArgumentNullException ex) { return new BadRequestObjectResult(ex.Message) {}; } catch (KeyNotFoundException ex) { return new BadRequestObjectResult(ex.Message) {}; } catch (Exception ex) { return new ObjectResult(ex.Message) { StatusCode = 500 }; } } /// /// Create a group /// /// Group to create [ProducesResponseType(typeof(GroupDetailDTO), 200)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 500)] [HttpPost] public ObjectResult Create([FromBody] GroupCreateOrUpdateDetailDTO groupCreateOrUpdateDetail) { try { if (groupCreateOrUpdateDetail == null) throw new ArgumentNullException("Incorrect parameters"); GroupDetailDTO groupCreated = GroupService.CreateOrUpdate(this._GroupDatabaseService, this._DeviceDatabaseService, groupCreateOrUpdateDetail.UserId, groupCreateOrUpdateDetail, true); return new OkObjectResult(groupCreated); } catch (ArgumentNullException ex) { return new BadRequestObjectResult(ex.Message) {}; } catch (Exception ex) { return new ObjectResult(ex.Message) { StatusCode = 500 }; } } /// /// Create groups from provider /// /// User Id [ProducesResponseType(typeof(List), 200)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] [HttpPost("{userId}/fromZigbee")] public ObjectResult CreateDevicesFromZigbee2Mqtt(string userId) { try { if (userId == null) throw new ArgumentNullException("Incorrect parameters"); if (!UserService.IsExist(_UserDatabaseService, userId)) throw new KeyNotFoundException("User not found"); Provider provider = _ProviderDatabaseService.GetByType("zigbee2mqtt"); if (provider == null) throw new KeyNotFoundException("Zigbee2mqtt provider not found"); // GET ALL LOCAL GROUPS var groups = MqttClientService.groups; // Be carefull, we only got the exact result after each connection List groupsDetail= GroupService.CreateFromZigbeeAsync(_GroupDatabaseService, _DeviceDatabaseService, userId, groups); return new OkObjectResult(groupsDetail); } catch (ArgumentNullException ex) { return new BadRequestObjectResult(ex.Message) {}; } catch (KeyNotFoundException ex) { return new BadRequestObjectResult(ex.Message) {}; } catch (Exception ex) { return new ObjectResult(ex.Message) { StatusCode = 500 }; } } /// /// Update a group /// /// group to update [ProducesResponseType(typeof(GroupCreateOrUpdateDetailDTO), 200)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] [HttpPut] public ObjectResult Update([FromBody] GroupCreateOrUpdateDetailDTO groupCreateOrUpdateDetail) { try { if (groupCreateOrUpdateDetail == null) throw new ArgumentNullException("Incorrect parameters"); if (!_GroupDatabaseService.IsExist(groupCreateOrUpdateDetail.Id)) throw new KeyNotFoundException("Group does not exist"); GroupDetailDTO groupUpdated = GroupService.CreateOrUpdate(this._GroupDatabaseService, this._DeviceDatabaseService, groupCreateOrUpdateDetail.UserId, groupCreateOrUpdateDetail, false); return new OkObjectResult(groupUpdated); } catch (ArgumentNullException ex) { return new BadRequestObjectResult(ex.Message) {}; } catch (KeyNotFoundException ex) { return new NotFoundObjectResult(ex.Message) {}; } catch (Exception ex) { return new ObjectResult(ex.Message) { StatusCode = 500 }; } } /// /// Delete device from a group /// /// Id of device to delete from the group /// Id of group [ProducesResponseType(typeof(string), 202)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] [HttpDelete("{groupId}/device/{deviceId}")] public ObjectResult Delete(string deviceId, string groupId) { try { if (groupId == null || deviceId == null) throw new ArgumentNullException("Incorrect parameters"); if (!_GroupDatabaseService.IsExist(groupId)) throw new KeyNotFoundException("Group does not exist"); // Update group Group group = _GroupDatabaseService.GetById(groupId); group.DevicesIds = group.DevicesIds.Where(d => d != deviceId).ToList(); group.UpdatedDate = DateTime.Now; _GroupDatabaseService.Update(group); // Update device Device device = _DeviceDatabaseService.GetById(deviceId); if (device == null) throw new KeyNotFoundException("Device does not exist"); device.GroupIds = device.GroupIds.Where(g => g != groupId).ToList(); device.UpdatedDate = DateTime.Now; _DeviceDatabaseService.Update(device); return new ObjectResult("Device has been successfully removed from specified group") { StatusCode = 202 }; } catch (ArgumentNullException ex) { return new BadRequestObjectResult(ex.Message) {}; } catch (KeyNotFoundException ex) { return new NotFoundObjectResult(ex.Message) {}; } catch (Exception ex) { return new ObjectResult(ex.Message) { StatusCode = 500 }; } } /// /// Delete a group /// /// Id of group to delete [ProducesResponseType(typeof(string), 202)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] [HttpDelete("{groupId}")] public ObjectResult Delete(string groupId) { try { if (groupId == null) throw new ArgumentNullException("Incorrect parameters"); if (!_GroupDatabaseService.IsExist(groupId)) throw new KeyNotFoundException("Group does not exist"); Group group = _GroupDatabaseService.GetById(groupId); // Delete group from all devices List devices = _DeviceDatabaseService.GetByLocation(group.UserId, groupId); foreach (var device in devices) { device.GroupIds = device.GroupIds.Where(g => g != groupId).ToList(); device.UpdatedDate = DateTime.Now; _DeviceDatabaseService.Update(device); } // Delete group _GroupDatabaseService.Remove(groupId); return new ObjectResult("The group has been successfully deleted") { StatusCode = 202 }; } catch (ArgumentNullException ex) { return new BadRequestObjectResult(ex.Message) {}; } catch (KeyNotFoundException ex) { return new NotFoundObjectResult(ex.Message) {}; } catch (Exception ex) { return new ObjectResult(ex.Message) { StatusCode = 500 }; } } /// /// Delete all group for a specified /// /// Id of user [ProducesResponseType(typeof(string), 202)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] [HttpDelete("user/{userId}")] public ObjectResult DeleteAllForUser(string userId) { try { if (userId == null) throw new ArgumentNullException("Incorrect parameters"); if (!_UserDatabaseService.IsExist(userId)) throw new KeyNotFoundException("User does not exist"); _GroupDatabaseService.RemoveForUser(userId); return new ObjectResult("All group linked with specified user has been successfully deleted") { StatusCode = 202 }; } catch (ArgumentNullException ex) { return new BadRequestObjectResult(ex.Message) {}; } catch (KeyNotFoundException ex) { return new NotFoundObjectResult(ex.Message) {}; } catch (Exception ex) { return new ObjectResult(ex.Message) { StatusCode = 500 }; } } } }