using Coscine.Database.DataModel;
using Coscine.Database.Models;
using Coscine.Metadata;
using VDS.RDF;

namespace SQL2Linked.Implementations
{
    public class UserStructuralData : StructuralData<User, UserModel>
    {
        public readonly string UserUrlPrefix = "https://purl.org/coscine/users";
        public readonly Uri rdf = new("http://www.w3.org/1999/02/22-rdf-syntax-ns#");
        public readonly Uri foaf = new("http://xmlns.com/foaf/0.1/");

        public override IEnumerable<IGraph> ConvertToLinkedData(IEnumerable<User> entries)
        {
            var graphs = new List<IGraph>();

            foreach (var entry in entries)
            {
                var userGraphName = $"{UserUrlPrefix}/{entry.Id}";
                var graph = RdfStoreConnector.GetGraph(userGraphName);

                // check if a triple with a foaf:Person already exists in the user graph
                var getTriples = graph.GetTriplesWithObject(new Uri(foaf + "Person"));
                // check if the current display name is already applied in the user graph
                var getTriplesName = graph.GetTriplesWithPredicate(new Uri(foaf + "name"));

                if (!getTriples.Any() || !getTriplesName.Any((triple) => triple.Object.ToString() == entry.DisplayName))
                {
                    AssertToGraphUriNode(graph, userGraphName, rdf + "type", foaf + "Person");

                    graph.Retract(getTriplesName);
                    AssertToGraphLiteralNode(graph, userGraphName, foaf + "name", entry.DisplayName);

                    graphs.Add(graph);

                    Console.WriteLine($"Will migrate user '{entry.DisplayName}' with id '{entry.Id}'.");
                }
                else
                {
                    Console.WriteLine($"Will NOT migrate user '{entry.DisplayName}' with id '{entry.Id}'.");
                }
            }
            return graphs;
        }
    }
}