/*==========================================================================================================================
        | GET CONTROLLER INSTANCE
        \-------------------------------------------------------------------------------------------------------------------------*/
        /// <summary>
        ///   Overrides the factory method for creating new instances of controllers.
        /// </summary>
        /// <returns>A concrete instance of an <see cref="IController"/>.</returns>
        protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
        {
            /*------------------------------------------------------------------------------------------------------------------------
            | Register
            \-----------------------------------------------------------------------------------------------------------------------*/
            var mvcTopicRoutingService = new MvcTopicRoutingService(
                _topicRepository,
                requestContext.HttpContext.Request.Url,
                requestContext.RouteData
                );

            /*------------------------------------------------------------------------------------------------------------------------
            | Resolve
            \-----------------------------------------------------------------------------------------------------------------------*/
            switch (controllerType.Name)
            {
            case nameof(RedirectController):
                return(new RedirectController(_topicRepository));

            case nameof(SitemapController):
                return(new SitemapController(_topicRepository));

            case nameof(ErrorController):
                return(new ErrorController());

            case nameof(LayoutController):
                return(new LayoutController(mvcTopicRoutingService, _hierarchicalTopicMappingService, _topicRepository));

            case nameof(TopicController):
                return(new TopicController(_topicRepository, mvcTopicRoutingService, _topicMappingService));

            default:
                return(base.GetControllerInstance(requestContext, controllerType));
            }
        }
    public void TopicUri() {

      var routes                = new RouteData();
      var uri                   = new Uri("http://localhost/Web/Web_0/Web_0_1/Web_0_1_1");
      var topic                 = _topicRepository.Load("Root:Web:Web_0:Web_0_1:Web_0_1_1");

      var topicRoutingService   = new MvcTopicRoutingService(_topicRepository, uri, routes);
      var currentTopic          = topicRoutingService.GetCurrentTopic();

      Assert.IsNotNull(currentTopic);
      Assert.ReferenceEquals(topic, currentTopic);
      Assert.AreEqual<string>("Web_0_1_1", currentTopic.Key);

    }
    public async Task TopicController_IndexAsync() {

      var topicRoutingService   = new MvcTopicRoutingService(_topicRepository, _uri, _routeData);
      var mappingService        = new TopicMappingService(_topicRepository, new TopicViewModelLookupService());

      var controller            = new TopicController(_topicRepository, topicRoutingService, mappingService);
      var result                = await controller.IndexAsync(_topic.GetWebPath()).ConfigureAwait(false) as TopicViewResult;
      var model                 = result.Model as PageTopicViewModel;

      controller.Dispose();

      Assert.IsNotNull(model);
      Assert.AreEqual<string>("Web_0_1_1", model.Title);

    }
    public void Routes() {

      var routes                = new RouteData();
      var uri                   = new Uri("http://localhost/Web/Web_0/Web_0_1/Web_0_1_1");

      routes.Values.Add("rootTopic", "Web");
      routes.Values.Add("path", "Web_0/Web_0_1/Web_0_1_1");

      var topicRoutingService   = new MvcTopicRoutingService(_topicRepository, uri, routes);
      var currentTopic          = topicRoutingService.GetCurrentTopic();

      Assert.IsNotNull(currentTopic);
      Assert.AreEqual<string>("Web", routes.GetRequiredString("rootTopic"));
      Assert.AreEqual<string>("Web_0/Web_0_1/Web_0_1_1", routes.GetRequiredString("path"));
      Assert.AreEqual<string>("Page", routes.GetRequiredString("contenttype"));

    }
    /*==========================================================================================================================
    | METHOD: CREATE PAGE-LEVEL NAVIGATION VIEW COMPONENT
    \-------------------------------------------------------------------------------------------------------------------------*/
    /// <summary>
    ///   Responds to a request to create a <see cref="MenuViewComponent"/> instance.
    /// </summary>
    private PageLevelNavigationViewComponent CreatePageLevelNavigationViewComponent(ViewComponentContext context) {

      /*------------------------------------------------------------------------------------------------------------------------
      | Register
      \-----------------------------------------------------------------------------------------------------------------------*/
      var mvcTopicRoutingService = new MvcTopicRoutingService(
        _topicRepository,
        new Uri($"https://{context.ViewContext.HttpContext.Request.Host}/{context.ViewContext.HttpContext.Request.Path}"),
        context.ViewContext.RouteData
      );

      /*------------------------------------------------------------------------------------------------------------------------
      | Return MenuViewComponent
      \-----------------------------------------------------------------------------------------------------------------------*/
      return new PageLevelNavigationViewComponent(mvcTopicRoutingService, _hierarchicalMappingService);

    }
    /*==========================================================================================================================
    | METHOD: CREATE TOPIC CONTROLLER
    \-------------------------------------------------------------------------------------------------------------------------*/
    /// <summary>
    ///   Responds to a request to create a <see cref="TopicController"/> instance, the default controller for the site.
    /// </summary>
    private TopicController CreateTopicController(ControllerContext context) {

      /*------------------------------------------------------------------------------------------------------------------------
      | Register
      \-----------------------------------------------------------------------------------------------------------------------*/
      var mvcTopicRoutingService = new MvcTopicRoutingService(
        _topicRepository,
        new Uri($"https://{context.HttpContext.Request.Host}/{context.HttpContext.Request.Path}"),
        context.RouteData
      );

      /*------------------------------------------------------------------------------------------------------------------------
      | Return TopicController
      \-----------------------------------------------------------------------------------------------------------------------*/
      return new TopicController(_topicRepository, mvcTopicRoutingService, _topicMappingService);

    }
    public async Task Menu() {

      var topicRoutingService   = new MvcTopicRoutingService(_topicRepository, _uri, _routeData);
      var mappingService        = new HierarchicalTopicMappingService<NavigationTopicViewModel>(
        _topicRepository,
        new TopicMappingService(
          _topicRepository,
          new TopicViewModelLookupService()
        )
      );

      var controller            = new LayoutController(topicRoutingService, mappingService);
      var result                = await controller.Menu().ConfigureAwait(false) as PartialViewResult;
      var model                 = result.Model as NavigationViewModel<NavigationTopicViewModel>;

      controller.Dispose();

      Assert.IsNotNull(model);
      Assert.AreEqual<string>(_topic.GetUniqueKey(), model.CurrentKey);
      Assert.AreEqual<string>("Root:Web", model.NavigationRoot.UniqueKey);
      Assert.AreEqual<int>(3, model.NavigationRoot.Children.Count());
      Assert.IsTrue(model.NavigationRoot.IsSelected(_topic.GetUniqueKey()));

    }