using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.Routing;
using System;
using System.Collections.Generic;
using Timeline.Controllers;
namespace Timeline.Models.Http
{
///
/// Info of post content.
///
public class HttpTimelinePostContent
{
///
/// Type of the post content.
///
public string Type { get; set; } = default!;
///
/// If post is of text type. This is the text.
///
public string? Text { get; set; }
///
/// If post is of image type. This is the image url.
///
public string? Url { get; set; }
///
/// If post has data (currently it means it's a image post), this is the data etag.
///
public string? ETag { get; set; }
}
///
/// Info of a post.
///
public class HttpTimelinePost
{
///
/// Post id.
///
public long Id { get; set; }
///
/// Content of the post. May be null if post is deleted.
///
public HttpTimelinePostContent? Content { get; set; }
///
/// True if post is deleted.
///
public bool Deleted { get; set; }
///
/// Post time.
///
public DateTime Time { get; set; }
///
/// The author. May be null if the user has been deleted.
///
public HttpUser? Author { get; set; } = default!;
///
/// Last updated time.
///
public DateTime LastUpdated { get; set; } = default!;
}
///
/// Info of a timeline.
///
public class HttpTimeline
{
///
/// Unique id.
///
public string UniqueId { get; set; } = default!;
///
/// Title.
///
public string Title { get; set; } = default!;
///
/// Name of timeline.
///
public string Name { get; set; } = default!;
///
/// Last modified time of timeline name.
///
public DateTime NameLastModifed { get; set; } = default!;
///
/// Timeline description.
///
public string Description { get; set; } = default!;
///
/// Owner of the timeline.
///
public HttpUser Owner { get; set; } = default!;
///
/// Visibility of the timeline.
///
public TimelineVisibility Visibility { get; set; }
#pragma warning disable CA2227 // Collection properties should be read only
///
/// Members of timeline.
///
public List Members { get; set; } = default!;
#pragma warning restore CA2227 // Collection properties should be read only
///
/// Create time of timeline.
///
public DateTime CreateTime { get; set; } = default!;
///
/// Last modified time of timeline.
///
public DateTime LastModified { get; set; } = default!;
#pragma warning disable CA1707 // Identifiers should not contain underscores
///
/// Related links.
///
public HttpTimelineLinks _links { get; set; } = default!;
#pragma warning restore CA1707 // Identifiers should not contain underscores
}
///
/// Related links for timeline.
///
public class HttpTimelineLinks
{
///
/// Self.
///
public string Self { get; set; } = default!;
///
/// Posts url.
///
public string Posts { get; set; } = default!;
}
public class HttpTimelineLinksValueResolver : IValueResolver
{
private readonly IActionContextAccessor _actionContextAccessor;
private readonly IUrlHelperFactory _urlHelperFactory;
public HttpTimelineLinksValueResolver(IActionContextAccessor actionContextAccessor, IUrlHelperFactory urlHelperFactory)
{
_actionContextAccessor = actionContextAccessor;
_urlHelperFactory = urlHelperFactory;
}
public HttpTimelineLinks Resolve(TimelineInfo source, HttpTimeline destination, HttpTimelineLinks destMember, ResolutionContext context)
{
var actionContext = _actionContextAccessor.AssertActionContextForUrlFill();
var urlHelper = _urlHelperFactory.GetUrlHelper(actionContext);
return new HttpTimelineLinks
{
Self = urlHelper.ActionLink(nameof(TimelineController.TimelineGet), nameof(TimelineController)[0..^nameof(Controller).Length], new { source.Name }),
Posts = urlHelper.ActionLink(nameof(TimelineController.PostListGet), nameof(TimelineController)[0..^nameof(Controller).Length], new { source.Name })
};
}
}
public class HttpTimelinePostContentResolver : IValueResolver
{
private readonly IActionContextAccessor _actionContextAccessor;
private readonly IUrlHelperFactory _urlHelperFactory;
public HttpTimelinePostContentResolver(IActionContextAccessor actionContextAccessor, IUrlHelperFactory urlHelperFactory)
{
_actionContextAccessor = actionContextAccessor;
_urlHelperFactory = urlHelperFactory;
}
public HttpTimelinePostContent? Resolve(TimelinePostInfo source, HttpTimelinePost destination, HttpTimelinePostContent? destMember, ResolutionContext context)
{
var actionContext = _actionContextAccessor.AssertActionContextForUrlFill();
var urlHelper = _urlHelperFactory.GetUrlHelper(actionContext);
var sourceContent = source.Content;
if (sourceContent == null)
{
return null;
}
if (sourceContent is TextTimelinePostContent textContent)
{
return new HttpTimelinePostContent
{
Type = TimelinePostContentTypes.Text,
Text = textContent.Text
};
}
else if (sourceContent is ImageTimelinePostContent imageContent)
{
return new HttpTimelinePostContent
{
Type = TimelinePostContentTypes.Image,
Url = urlHelper.ActionLink(
action: nameof(TimelineController.PostDataGet),
controller: nameof(TimelineController)[0..^nameof(Controller).Length],
values: new { Name = source.TimelineName, Id = source.Id }),
ETag = $"\"{imageContent.DataTag}\""
};
}
else
{
throw new InvalidOperationException(Resources.Models.Http.Exception.UnknownPostContentType);
}
}
}
public class HttpTimelineAutoMapperProfile : Profile
{
public HttpTimelineAutoMapperProfile()
{
CreateMap().ForMember(u => u._links, opt => opt.MapFrom());
CreateMap().ForMember(p => p.Content, opt => opt.MapFrom());
}
}
}