<commit_before>/**
 * Copyright Notice
 *
 * This is a work of the U.S. Government and is not subject to copyright
 * protection in the United States. Foreign copyrights may apply.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package gov.va.oia.terminology.converters.sharedUtils;

import gov.va.oia.terminology.converters.sharedUtils.propertyTypes.BPT_Descriptions;
import gov.va.oia.terminology.converters.sharedUtils.propertyTypes.BPT_MemberRefsets;
import gov.va.oia.terminology.converters.sharedUtils.propertyTypes.BPT_Relations;
import gov.va.oia.terminology.converters.sharedUtils.propertyTypes.BPT_Skip;
import gov.va.oia.terminology.converters.sharedUtils.propertyTypes.Property;
import gov.va.oia.terminology.converters.sharedUtils.propertyTypes.PropertyType;
import gov.va.oia.terminology.converters.sharedUtils.propertyTypes.ValuePropertyPair;
import gov.va.oia.terminology.converters.sharedUtils.stats.ConverterUUID;
import gov.va.oia.terminology.converters.sharedUtils.stats.LoadStats;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import org.apache.commons.lang.StringUtils;
import org.dwfa.ace.refset.ConceptConstants;
import org.dwfa.cement.ArchitectonicAuxiliary;
import org.dwfa.cement.RefsetAuxiliary;
import org.dwfa.util.id.Type5UuidFactory;
import org.ihtsdo.etypes.EConcept;
import org.ihtsdo.etypes.EConceptAttributes;
import org.ihtsdo.etypes.EIdentifierLong;
import org.ihtsdo.etypes.EIdentifierString;
import org.ihtsdo.etypes.EIdentifierUuid;
import org.ihtsdo.tk.binding.snomed.RefsetAux;
import org.ihtsdo.tk.binding.snomed.Snomed;
import org.ihtsdo.tk.binding.snomed.SnomedMetadataRf2;
import org.ihtsdo.tk.binding.snomed.TermAux;
import org.ihtsdo.tk.dto.concept.component.TkComponent;
import org.ihtsdo.tk.dto.concept.component.TkRevision;
import org.ihtsdo.tk.dto.concept.component.attribute.TkConceptAttributes;
import org.ihtsdo.tk.dto.concept.component.description.TkDescription;
import org.ihtsdo.tk.dto.concept.component.identifier.TkIdentifier;
import org.ihtsdo.tk.dto.concept.component.refex.TkRefexAbstractMember;
import org.ihtsdo.tk.dto.concept.component.refex.type_string.TkRefsetStrMember;
import org.ihtsdo.tk.dto.concept.component.refex.type_uuid.TkRefexUuidMember;
import org.ihtsdo.tk.dto.concept.component.refex.type_uuid_int.TkRefexUuidIntMember;
import org.ihtsdo.tk.dto.concept.component.relationship.TkRelationship;

/**
 * 
 * {@link EConceptUtility}
 * 
 * Various constants and methods for building up workbench EConcepts.
 * 
 * A much easier interfaces to use than trek - takes care of boilerplate stuff for you.
 * Also, forces consistency in how things are converted.
 *
 * @author <a href="mailto:<EMAIL>"><NAME></a>
 */
public class EConceptUtility
{
	public static enum DescriptionType{FSN, SYNONYM, DEFINITION};
	public static final UUID isARelUuid_ = Snomed.IS_A.getUuids()[0];
	public final UUID authorUuid_ = ArchitectonicAuxiliary.Concept.USER.getPrimoridalUid();
	public final UUID statusCurrentUuid_ = SnomedMetadataRf2.ACTIVE_VALUE_RF2.getUuids()[0];
	public final UUID statusRetiredUuid_ = SnomedMetadataRf2.INACTIVE_VALUE_RF2.getUuids()[0];
	public final UUID synonymUuid_ = SnomedMetadataRf2.SYNONYM_RF2.getUuids()[0];
	public final UUID definitionUuid_ = SnomedMetadataRf2.DEFINITION_RF2.getUuids()[0];
	public final UUID fullySpecifiedNameUuid_ = SnomedMetadataRf2.FULLY_SPECIFIED_NAME_RF2.getUuids()[0];
	public final UUID descriptionAcceptableUuid_ = SnomedMetadataRf2.ACCEPTABLE_RF2.getUuids()[0];
	public final UUID descriptionPreferredUuid_ = SnomedMetadataRf2.PREFERRED_RF2.getUuids()[0];
	public final UUID usEnRefsetUuid_ = SnomedMetadataRf2.US_ENGLISH_REFSET_RF2.getUuids()[0];
	public final UUID definingCharacteristicUuid_ = SnomedMetadataRf2.STATED_RELATIONSHIP_RF2.getUuids()[0];
	public final UUID notRefinableUuid = SnomedMetadataRf2.NOT_REFINABLE_RF2.getUuids()[0];
	public final UUID moduleUuid_ = TkRevision.unspecifiedModuleUuid;
	public final UUID refsetMemberTypeNormalMemberUuid_ = RefsetAuxiliary.Concept.NORMAL_MEMBER.getPrimoridalUid();
	public final String PROJECT_REFSETS_NAME = "Project Refsets";
	public final UUID PROJECT_REFSETS_UUID = UUID.fromString("7fe3e31f-a969-53ff-8702-f7837e4a03d9");  //This is Type5UuidFactory.PATH_ID_FROM_FS_DESC, "Project Refsets")
	public final UUID pathOriginRefSetUUID_ = RefsetAux.PATH_ORIGIN_REFEST.getUuids()[0];
	public final UUID pathRefSetUUID_ = RefsetAux.PATH_REFSET.getUuids()[0];
	public final UUID pathUUID_ = ArchitectonicAuxiliary.Concept.PATH.getPrimoridalUid();
	public final UUID pathReleaseUUID_ =  ArchitectonicAuxiliary.Concept.RELEASE.getPrimoridalUid();
	public final UUID workbenchAuxilary = TermAux.WB_AUX_PATH.getUuids()[0];
	public final long defaultTime_;
	
	private UUID wbPropertyMetadataDescUUID = null;
	private UUID wbPropertyMetadataRelUUID = null;
	
	private final String lang_ = "en";
	private UUID terminologyPathUUID_ = workbenchAuxilary;  //start with this.

	private LoadStats ls_ = new LoadStats();

	/**
	 * Creates and stores the path concept - sets up the various namespace details.
	 * @param namespaceSeed The string to use for seeing the UUID generator for this namespace
	 * @param pathName The name to use for the concept that will be created as the 'path' concept
	 * @param defaultTime - the timestamp to place on created elements, when no other timestamp is specified on the element itself.
	 * @param dos - location to write the output
	 * @throws Exception
	 */
	public EConceptUtility(String namespaceSeed, String pathName, DataOutputStream dos, long defaultTime) throws Exception
	{
		ConverterUUID.addMapping("isA", isARelUuid_);
		ConverterUUID.addMapping("Synonym", synonymUuid_);
		ConverterUUID.addMapping("Fully Specified Name", fullySpecifiedNameUuid_);
		ConverterUUID.addMapping("US English Refset", usEnRefsetUuid_);
		ConverterUUID.addMapping("Path reference set", pathRefSetUUID_);
		ConverterUUID.addMapping("Path origin reference set", pathOriginRefSetUUID_);
		
		defaultTime_ = defaultTime;
		
		UUID namespace = ConverterUUID.createNamespaceUUIDFromString(null, namespaceSeed);
		ConverterUUID.configureNamespace(namespace);
		
		//Start our creating our path concept, by hanging it under path/release
		//Note, this concept gets created on WorkbenchAuxiliary path.
		//need to gen the UUID on the special namespace, so it can be targeted from assembly pom
		EConcept c = createConcept(ConverterUUID.createNamespaceUUIDFromString(Type5UuidFactory.PATH_ID_FROM_FS_DESC, pathName), pathName, pathReleaseUUID_);  
		addDescription(c, pathName, DescriptionType.SYNONYM, true, null, null, false);  //Need a synonym as well, to be able to target from assembly pom
		c.writeExternal(dos);
		
		//Add it to the pathOriginRefSet, done on workbenchAux path.
		EConcept pathOriginRefsetConcept = createConcept(pathOriginRefSetUUID_);
		//Max value will be displayed as 'latest'.  Why on earth we are using an int for a time value, I have no idea.
		addRefsetMember(pathOriginRefsetConcept, c.getPrimordialUuid(), workbenchAuxilary, Integer.MAX_VALUE, true, null);
		pathOriginRefsetConcept.writeExternal(dos);
		
		//Also, add it to the pathRefset.  Also done on WorkbenchAux path.
		EConcept pathRefsetConcept = createConcept(pathRefSetUUID_);
		addRefsetMember(pathRefsetConcept, pathUUID_, c.getPrimordialUuid(), true, null);
		pathRefsetConcept.writeExternal(dos);
		
		terminologyPathUUID_ = c.getPrimordialUuid();  //Now change the path to our new path concept
		ConsoleUtil.println("The path to be specified in the workbench baseline pom (or assembly pom) is '" + pathName + "' - " + terminologyPathUUID_);
	}

	/**
	 * Create a concept, automatically setting as many fields as possible (adds a description, calculates
	 * the UUID, status current, etc)
	 */
	public EConcept createConcept(String preferredDescription)<commit_msg>Preparing for release of bundle 4.1 with new approach to PCs<commit_after>/**
 * Copyright Notice
 *
 * This is a work of the U.S. Government and is not subject to copyright
 * protection in the United States. Foreign copyrights may apply.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package gov.va.oia.terminology.converters.sharedUtils;

import gov.va.oia.terminology.converters.sharedUtils.propertyTypes.BPT_Descriptions;
import gov.va.oia.terminology.converters.sharedUtils.propertyTypes.BPT_MemberRefsets;
import gov.va.oia.terminology.converters.sharedUtils.propertyTypes.BPT_Relations;
import gov.va.oia.terminology.converters.sharedUtils.propertyTypes.BPT_Skip;
import gov.va.oia.terminology.converters.sharedUtils.propertyTypes.Property;
import gov.va.oia.terminology.converters.sharedUtils.propertyTypes.PropertyType;
import gov.va.oia.terminology.converters.sharedUtils.propertyTypes.ValuePropertyPair;
import gov.va.oia.terminology.converters.sharedUtils.stats.ConverterUUID;
import gov.va.oia.terminology.converters.sharedUtils.stats.LoadStats;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import org.apache.commons.lang.StringUtils;
import org.dwfa.ace.refset.ConceptConstants;
import org.dwfa.cement.ArchitectonicAuxiliary;
import org.dwfa.cement.RefsetAuxiliary;
import org.dwfa.util.id.Type5UuidFactory;
import org.ihtsdo.etypes.EConcept;
import org.ihtsdo.etypes.EConceptAttributes;
import org.ihtsdo.etypes.EIdentifierLong;
import org.ihtsdo.etypes.EIdentifierString;
import org.ihtsdo.etypes.EIdentifierUuid;
import org.ihtsdo.tk.binding.snomed.RefsetAux;
import org.ihtsdo.tk.binding.snomed.Snomed;
import org.ihtsdo.tk.binding.snomed.SnomedMetadataRf2;
import org.ihtsdo.tk.binding.snomed.TermAux;
import org.ihtsdo.tk.dto.concept.component.TkComponent;
import org.ihtsdo.tk.dto.concept.component.TkRevision;
import org.ihtsdo.tk.dto.concept.component.attribute.TkConceptAttributes;
import org.ihtsdo.tk.dto.concept.component.description.TkDescription;
import org.ihtsdo.tk.dto.concept.component.identifier.TkIdentifier;
import org.ihtsdo.tk.dto.concept.component.refex.TkRefexAbstractMember;
import org.ihtsdo.tk.dto.concept.component.refex.type_string.TkRefsetStrMember;
import org.ihtsdo.tk.dto.concept.component.refex.type_uuid.TkRefexUuidMember;
import org.ihtsdo.tk.dto.concept.component.refex.type_uuid_int.TkRefexUuidIntMember;
import org.ihtsdo.tk.dto.concept.component.relationship.TkRelationship;

/**
 * 
 * {@link EConceptUtility}
 * 
 * Various constants and methods for building up workbench EConcepts.
 * 
 * A much easier interfaces to use than trek - takes care of boilerplate stuff for you.
 * Also, forces consistency in how things are converted.
 *
 * @author <a href="mailto:<EMAIL>"><NAME></a>
 */
public class EConceptUtility
{
	public static enum DescriptionType{FSN, SYNONYM, DEFINITION};
	public static final UUID isARelUuid_ = Snomed.IS_A.getUuids()[0];
	public final UUID authorUuid_ = ArchitectonicAuxiliary.Concept.USER.getPrimoridalUid();
	public final UUID statusCurrentUuid_ = SnomedMetadataRf2.ACTIVE_VALUE_RF2.getUuids()[0];
	public final UUID statusRetiredUuid_ = SnomedMetadataRf2.INACTIVE_VALUE_RF2.getUuids()[0];
	public final UUID synonymUuid_ = SnomedMetadataRf2.SYNONYM_RF2.getUuids()[0];
	public final UUID definitionUuid_ = SnomedMetadataRf2.DEFINITION_RF2.getUuids()[0];
	public final UUID fullySpecifiedNameUuid_ = SnomedMetadataRf2.FULLY_SPECIFIED_NAME_RF2.getUuids()[0];
	public final UUID descriptionAcceptableUuid_ = SnomedMetadataRf2.ACCEPTABLE_RF2.getUuids()[0];
	public final UUID descriptionPreferredUuid_ = SnomedMetadataRf2.PREFERRED_RF2.getUuids()[0];
	public final UUID usEnRefsetUuid_ = SnomedMetadataRf2.US_ENGLISH_REFSET_RF2.getUuids()[0];
	public final UUID definingCharacteristicUuid_ = SnomedMetadataRf2.STATED_RELATIONSHIP_RF2.getUuids()[0];
	public final UUID notRefinableUuid = SnomedMetadataRf2.NOT_REFINABLE_RF2.getUuids()[0];
	public final UUID moduleUuid_ = TkRevision.unspecifiedModuleUuid;
	public final UUID refsetMemberTypeNormalMemberUuid_ = RefsetAuxiliary.Concept.NORMAL_MEMBER.getPrimoridalUid();
	public final String PROJECT_REFSETS_NAME = "Project Refsets";
	public final UUID PROJECT_REFSETS_UUID = UUID.fromString("7fe3e31f-a969-53ff-8702-f7837e4a03d9");  //This is Type5UuidFactory.PATH_ID_FROM_FS_DESC, "Project Refsets")
	public final UUID pathOriginRefSetUUID_ = RefsetAux.PATH_ORIGIN_REFEST.getUuids()[0];
	public final UUID pathRefSetUUID_ = RefsetAux.PATH_REFSET.getUuids()[0];
	public final UUID pathUUID_ = ArchitectonicAuxiliary.Concept.PATH.getPrimoridalUid();
	public final UUID pathReleaseUUID_ =  ArchitectonicAuxiliary.Concept.RELEASE.getPrimoridalUid();
	public final UUID workbenchAuxilary = TermAux.WB_AUX_PATH.getUuids()[0];
	public final long defaultTime_;
	
	private UUID wbPropertyMetadataDescUUID = null;
	private UUID wbPropertyMetadataRelUUID = null;
	
	private final String lang_ = "en";
	private UUID terminologyPathUUID_ = workbenchAuxilary;  //start with this.

	private LoadStats ls_ = new LoadStats();

	/**
	 * Creates and stores the path concept - sets up the various namespace details.
	 * @param namespaceSeed The string to use for seeing the UUID generator for this namespace
	 * @param pathName The name to use for the concept that will be created as the 'path' concept
	 * @param defaultTime - the timestamp to place on created elements, when no other timestamp is specified on the element itself.
	 * @param dos - location to write the output
	 * @throws Exception
	 */
	public EConceptUtility(String namespaceSeed, String pathName, DataOutputStream dos, long defaultTime) throws Exception
	{
		ConverterUUID.addMapping("isA", isARelUuid_);
		ConverterUUID.addMapping("Synonym", synonymUuid_);
		ConverterUUID.addMapping("Fully Specified Name", fullySpecifiedNameUuid_);
		ConverterUUID.addMapping("US English Refset", usEnRefsetUuid_);
		ConverterUUID.addMapping("Path reference set", pathRefSetUUID_);
		ConverterUUID.addMapping("Path origin reference set", pathOriginRefSetUUID_);
		
		defaultTime_ = defaultTime;
		
		UUID namespace = ConverterUUID.createNamespaceUUIDFromString(null, namespaceSeed);
		ConverterUUID.configureNamespace(namespace);
		
		//Start our creating our path concept, by hanging it under path/release
		//Note, this concept gets created on WorkbenchAuxiliary path.
		//need to gen the UUID on the special namespace, so it can be targeted from assembly pom
		EConcept c = createConcept(ConverterUUID.createNamespaceUUIDFromString(Type5UuidFactory.PATH_ID_FROM_FS_DESC, pathName), pathName, pathReleaseUUID_);  
		addDescription(c, pathName, DescriptionType.SYNONYM, true, null, null, false);  //Need a synonym as well, to be able to target from assembly pom
		c.writeExternal(dos);
		
		//Add it to the pathOriginRefSet, done on workbenchAux path.
		EConcept pathOriginRefsetConcept = createConcept(pathOriginRefSetUUID_);
		//Max value will be displayed as 'latest'.  Why on earth we are using an int for a time value, I have no idea.
		addRefsetMember(pathOriginRefsetConcept, c.getPrimordialUuid(), workbenchAuxilary, Integer.MAX_VALUE, true, null);
		pathOriginRefsetConcept.writeExternal(dos);
		
		//Also, add it to the pathRefset.  Also done on WorkbenchAux path.
		EConcept pathRefsetConcept = createConcept(pathRefSetUUID_);
		addRefsetMember(pathRefsetConcept, pathUUID_, c.getPrimordialUuid(), true, null);
		pathRefsetConcept.writeExternal(dos);
		
		terminologyPathUUID_ = c.getPrimordialUuid();  //Now change the path to our new path concept
		ConsoleUtil.println("The path to be specified in the workbench baseline pom (or assembly pom) is '" + pathName + "' - " + terminologyPathUUID_);
	}

	public EConceptUtility(String namespaceSeed, DataOutputStream dos, long defaultTime) throws Exception
	{
		ConverterUUID.addMapping("isA", isARelUuid_);
		ConverterUUID.addMapping("Synonym", synonymUuid_);
		ConverterUUID.addMapping("Fully Specified Name", fullySpecifiedNameUuid_);
		ConverterUUID.addMapping("US English Refset", usEnRefsetUuid_);
		ConverterUUID.addMapping("Path reference set", pathRefSetUUID_);
		ConverterUUID.addMapping("Path origin reference set", pathOriginRefSetUUID_);
		
		defaultTime_ = defaultTime;
		
		UUID namespace = ConverterUUID.createNamespaceUUIDFromString(null, namespaceSeed);
		ConverterUUID.configureNamespace(namespace);

		String pathName = "JIF Terminology Workbench development path";
		UUID pathUuid = UUID.fromString("944355c4-6eee-5fef-b8cc-fb0f500878ef"); // UUID for JIF Term WB Dev Path
		
		terminologyPathUUID_ = pathUuid;  //Now change the path to our new path concept
 
		ConsoleUtil.println("The path to be specified in the workbench baseline pom (or assembly pom) is '" + pathName + "' - " + terminologyPathUUID_);
	}

	/**
	 * Create a concept, automatically setting as many fields as possible (adds a description, calculates
	 * the UUID, status current, etc)
	 */
	public EConcept createConcept(String preferredDescription)
{'fraction_non_alphanumeric': 0.08711433756805807, 'fraction_numerical': 0.007974481658692184, 'mean_word_length': 5.785074626865671, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6275608', 'n_tokens_mistral': 5995, 'n_tokens_neox': 5832, 'n_words': 1410}