
enum ItemReference {

    case general

    case post(Post)

    case feed

    case page(Page)

    case tagPage(Tag)

    case tagOverview
}

extension ItemReference: Equatable {

}

extension ItemReference: Hashable {

}

extension ItemReference: Identifiable {

    var id: String {
        switch self {
        case .general:
            return "0-general"
        case .feed:
            return "1-feed"
        case .post(let post):
            return "2-post-\(post.identifier)"
        case .page(let page):
            return "3-page-\(page.identifier)"
        case .tagPage(let tag):
            return "5-tag-\(tag.identifier)"
        case .tagOverview:
            return "4-tag-overview"
        }
    }

    init?(context: LoadingContext, rawValue: String) {
        if rawValue == "0-general" {
            self = .general
        } else if rawValue == "1-feed" {
            self = .feed
        } else if rawValue == "4-tag-overview" {
            self = .tagOverview
        } else if let id = rawValue.removingPrefix("3-page-"), let page = context.page(id) {
            self = .page(page)
        } else if let id = rawValue.removingPrefix("2-post-"), let post = context.post(id) {
            self = .post(post)
        } else if let id = rawValue.removingPrefix("5-tag-"), let tag = context.tag(id) {
            self = .tagPage(tag)
        } else {
            return nil
        }
    }
}

extension ItemReference: Comparable {

    static func < (lhs: ItemReference, rhs: ItemReference) -> Bool {
        lhs.id < rhs.id
    }
}

extension ItemReference: CustomStringConvertible {

    var description: String {
        switch self {
        case .general:
            return "General"
        case .feed:
            return "Feed"
        case .post(let post):
            return "Post \(post.identifier)"
        case .page(let page):
            return "Page \(page.identifier)"
        case .tagPage(let tag):
            return "Tag \(tag.identifier)"
        case .tagOverview:
            return "Tag Overview"
        }
    }
}
