using System.ComponentModel;
using System.Net.Sockets;
using System.ComponentModel.DataAnnotations;
using Newtonsoft.Json;
using isnd.Data.Packages;
using NuGet.Versioning;
using System.Collections.Generic;
using System;
using isnd.Interfaces;
using NuGet.Protocol.Core.Types;
using NuGet.Protocol;
using NuGet.Packaging;
using NuGet.Packaging.Core;
using System.Threading.Tasks;

namespace isnd.Data.Catalog
{
    public class PackageDetails : Permalink, IObject, IPackageSearchMetadata
    {
        /// <summary>
        /// Creates a catalog entry
        /// </summary>
        /// <param name="pkg">package id</param>
        /// <param name="apiBase">api Base</param>
        /// <param name="uri">package permalink</param>
        /// <returns></returns>
        public PackageDetails(PackageVersion pkg, string apiBase, string uri): base(uri)
        { 
            PackageId = pkg.Package.Id;
            Version = pkg.FullString;
            Authors = $"{pkg.Package.Owner.FullName} <${pkg.Package.Owner.Email}>";
            packageContent = apiBase + pkg.NugetLink;
            CommitId = pkg.CommitId;
            CommitTimeStamp = pkg.LatestCommit.CommitTimeStamp;
            IsListed = !pkg.IsDeleted && pkg.Package.Public;
            // TODO Licence Project Urls, Summary, Title, etc ...
        }

        [JsonProperty("@type")]
        public string[] RefType { get; protected set; } = new string[] { "PackageDetails" };

        [JsonProperty("commitId")]
        public string CommitId { get; set; }

        [JsonProperty("commitTimeStamp")]
        public DateTimeOffset CommitTimeStamp { get; set; }

        /// <summary>
        /// Authors
        /// </summary>
        /// <value>string or array of strings</value>
        [JsonProperty("authors")]
        public string Authors { get; set; }

        /// <summary>
        /// The dependencies of the package, grouped by target framework
        /// </summary>
        /// <value>array of objects</value>
        public DependencyGroup[] dependencyGroups { get; set; } = Array.Empty<DependencyGroup>();

        /// <summary>
        /// The deprecation associated with the package
        /// </summary>
        /// <value></value>
        public Deprecation deprecation { get; set; }

        [JsonProperty("description")]
        public string Description { get; set; }
        
        [JsonProperty("iconUrl")]
        public Uri IconUrl { get; set; }

        public string language { get; set; }

       
        [JsonProperty("licenseUrl")]
        public Uri LicenseUrl { get; set; }

        public string licenseExpression { get; set; }

        public string minClientVersion { get; set; }

        [JsonProperty("projectUrl")]
        public Uri ProjectUrl { get; set; }


        [JsonProperty("requireLicenseAcceptance")]
        public bool RequireLicenseAcceptance { get; set; }

        [JsonProperty("summary")]
        public string Summary { get; set; }

        /// <summary>
        /// The tags
        /// </summary>
        /// <value></value>
        [JsonProperty("tags")]
        public string Tags { get; set; }
        
        [JsonProperty("title")]
        public string Title { get; set; }

        /// <summary>
        /// The security vulnerabilities of the package
        /// </summary>
        /// <value></value>
        public IEnumerable<PackageVulnerabilityMetadata> Vulnerabilities { get; }

        public string packageContent { get; set; }
   
        /// <summary>
        /// A string containing a ISO 8601 timestamp of when the package was published
        /// </summary>
        /// <value></value>
        [JsonProperty("published")]
        public DateTimeOffset? Published { get; set; }

        /// <summary>
        /// The full version string after normalization
        /// </summary>
        /// <value></value>
        [Required,JsonRequired]
        [JsonProperty("version")]
        public string Version { get; set; }

        [Required,JsonRequired]
        [JsonProperty("id")]
        public string PackageId { get;  set; }

        public IEnumerable<PackageDependencyGroup> DependencySets { get; set; }
         = Array.Empty<PackageDependencyGroup>();

        public long? DownloadCount { get; set; }

        public PackageIdentity Identity{ get; set; }

        public Uri ReadmeUrl { get; set; }

        public Uri ReportAbuseUrl { get; set; }

        public Uri PackageDetailsUrl { get; set; }

        public string Owners { get; set; }

        [JsonProperty("isListed")]
        public bool IsListed { get; set; }

        public bool PrefixReserved { get; set; }

        public LicenseMetadata LicenseMetadata { get; set; }

        public Task<PackageDeprecationMetadata> GetDeprecationMetadataAsync()
        {
            throw new NotImplementedException();
        }

        public Task<IEnumerable<VersionInfo>> GetVersionsAsync()
        {
            throw new NotImplementedException();
        }
    }
}