import java.nio.charset.CharsetEncoder
import java.nio.charset.StandardCharsets
import java.nio.file.Files
import java.nio.file.Paths
import java.text.DateFormat
import java.text.SimpleDateFormat
import java.util.UUID
import java.util.Map.Entry

import org.slf4j.Logger
import org.slf4j.LoggerFactory

import com.gridnine.xtrip.common.model.EntityContainer
import com.gridnine.xtrip.common.model.EntityReference
import com.gridnine.xtrip.common.model.dict.ContractType
import com.gridnine.xtrip.common.model.entity.EntityStorage
import com.gridnine.xtrip.common.model.profile.BaseProfile
import com.gridnine.xtrip.common.model.profile.Card
import com.gridnine.xtrip.common.model.profile.CardIndex
import com.gridnine.xtrip.common.model.profile.Contract
import com.gridnine.xtrip.common.model.profile.ContractCustomerIndex
import com.gridnine.xtrip.common.model.profile.Organization
import com.gridnine.xtrip.common.model.profile.OrganizationType
import com.gridnine.xtrip.common.model.profile.Person
import com.gridnine.xtrip.common.model.profile.PersonEmployment
import com.gridnine.xtrip.common.search.SearchCriterion
import com.gridnine.xtrip.common.search.SearchQuery
import com.gridnine.xtrip.common.search.SortOrder
import com.gridnine.xtrip.common.util.TextUtil

Logger logger = LoggerFactory.getLogger('groovy-script')

logger.info("CIR: cards delete started")

int processed = 0
int loops = 0

int deleted = 0

try {

    SearchQuery query = new SearchQuery()

    query.getCriteria().getOrders().put("containerUid", SortOrder.ASC)

    query.getPreferredProperties().add("containerUid")

    List<CardIndex> indexes = EntityStorage.get().search(CardIndex.class, query).getData()

    logger.info("CIR: found " + indexes.size() + " cards")

    for(CardIndex index : indexes) {

        logger.info("CIR: processing " + processed + " | " + index.getSource().getUid())

        if (Organization.class.isAssignableFrom(index.getSource().getType())) {
            
            EntityContainer<Organization> organizationContainer = EntityStorage.get().resolve((EntityReference<Organization>) index.getSource())

            if(organizationContainer != null) {

                Organization organization = organizationContainer.getEntity()

                if(organization.getCards().size() > 0) {
                
                    def count = organization.getCards().size()
                
                    organization.getCards().clear()
                
                    logger.info("CIR: found " + count + " card(s) of organization " + index.getSource() + " (" + index.getSource().getUid() + ")")
                
                    organizationContainer.getVersionInfo().setDataSource("cir-migration-2-5-task")
                
                    EntityStorage.get().save(organizationContainer, true)
                
                    deleted += count
                }
                
            } else {
                logger.info("CIR: unable to load organization " + index.getSource() + " (" + index.getSource().getUid() + ")")
            }
            
        } else if (Person.class.isAssignableFrom(index.getSource().getType())) {

            EntityContainer<Person> personContainer = EntityStorage.get().resolve((EntityReference<Person>) index.getSource())

            if(personContainer != null) {

                Person person = personContainer.getEntity()

                if(person.getCards().size() > 0) {
                
                    def count = person.getCards().size()
                
                    person.getCards().clear()
                
                    logger.info("CIR: found " + count + " card(s) of person " + index.getSource() + " (" + index.getSource().getUid() + ")")
                
                    personContainer.getVersionInfo().setDataSource("cir-migration-2-5-task")
                
                    EntityStorage.get().save(personContainer, true)
                
                    deleted += count
                }
                
            } else {
                logger.info("CIR: unable to load person " + index.getSource() + " (" + index.getSource().getUid() + ")")
            }
            
        } else {
            logger.info("CIR: unsupported profile type " + index.getSource() + " (" + index.getSource().getUid() + ")")
        }

        processed++
    }

} catch(Throwable t) {
    logger.error('', t)
}

logger.info("=================================")

logger.info("CIR: processed " + processed)
logger.info("CIR: deleted " + deleted)

logger.info("CIR: cards delete finished")
