import Foundation

struct Details : Codable {
    
	let post_count : Count?
	let album_count : Count?
	let following_count : Count?
	let followers_count : Count?
	let groups_count : Count?
	let likes_count : Count?
	let mutual_friends_count : Count?

	enum CodingKeys: String, CodingKey {
		case post_count = "post_count"
		case album_count = "album_count"
		case following_count = "following_count"
		case followers_count = "followers_count"
		case groups_count = "groups_count"
		case likes_count = "likes_count"
		case mutual_friends_count = "mutual_friends_count"
	}

	init(from decoder: Decoder) throws {
		let values = try decoder.container(keyedBy: CodingKeys.self)
		post_count = try values.decodeIfPresent(Count.self, forKey: .post_count)
		album_count = try values.decodeIfPresent(Count.self, forKey: .album_count)
		following_count = try values.decodeIfPresent(Count.self, forKey: .following_count)
		followers_count = try values.decodeIfPresent(Count.self, forKey: .followers_count)
		groups_count = try values.decodeIfPresent(Count.self, forKey: .groups_count)
		likes_count = try values.decodeIfPresent(Count.self, forKey: .likes_count)
		mutual_friends_count = try values.decodeIfPresent(Count.self, forKey: .mutual_friends_count)
	}

}

enum Count: Codable {
    
    case integer(Int)
    case string(String)
    case bool(Bool)
    
    var stringValue: String {
        switch self {
        case let .integer(value):
            return String(value)
        case let .string(value):
            return value
        case let .bool(value):
            return value == false ? String("0") : String("1")
        }
    }
    
    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        if let x = try? container.decode(Int.self) {
            self = .integer(x)
            return
        }
        if let x = try? container.decode(String.self) {
            self = .string(x)
            return
        }
        if let x = try? container.decode(Bool.self) {
            self = .bool(x)
            return
        }
        throw DecodingError.typeMismatch(Count.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for Count"))
    }
    
    func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        switch self {
        case .integer(let x):
            try container.encode(x)
        case .string(let x):
            try container.encode(x)
        case .bool(let x):
            try container.encode(x)
        }
    }
    
}
