/*
  * The contents of this file are subject to the Mozilla Public
  * License Version 1.1 (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.mozilla.org/MPL/
  *
  * Software distributed under the License is distributed on an
  * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
  * or implied. See the License for the specific language governing
  * rights and limitations under the License.
  *
  *
  * The Original Code is .NET RASP toolkit.
  *
  * The Initial Developer of the Original Code is Accenture and Avanade.
  * Portions created by Accenture and Avanade are Copyright (C) 2007
  * Danish National IT and Telecom Agency (http://www.itst.dk). 
  * All Rights Reserved.
  *
  * Contributor(s):
  *   Gert Sylvest (gerts@avanade.com)
  *   Patrik Johansson (p.johansson@accenture.com)
  *   Michael Nielsen (michaelni@avanade.com)
  *   Dennis Søgaard (dennis.j.sogaard@accenture.com)
  *   Ramzi Fadel (ramzif@avanade.com)
  *   Mikkel Hippe Brun (mhb@itst.dk)
  *   Finn Hartmann Jordal (fhj@itst.dk)
  *   Christian Lanng (chl@itst.dk)
  *
  */
using System;
using System.Collections.Generic;
using System.Text;
using dk.gov.oiosi.uddi.ars;
using dk.gov.oiosi.uddi.category;
using dk.gov.oiosi.uddi.identifier;
using dk.gov.oiosi.uddi;
using dk.gov.oiosi.addressing;

namespace dk.gov.oiosi.oioublProfileLibrary {
    
    /// <summary>
    /// Basic class created to get an overview of how ARS works.
    /// The class is only used by the UnitTests and can be deleted as such,
    /// but it provides a good overview of the steps needed to create a business entity with endpoints.
    /// </summary>
    public class OioublArs {
        
        /// <summary>
        /// Adds an process instance to an existing business entity
        /// </summary>
        /// <returns></returns>
        public string AddProcesInstanceToExistingBusinessEntity() {

            string cvr = "55555555";
            string name = "66 name " + DateTime.Now.ToLongTimeString();
            string description = "55555555 description";
            string certificateSubject = "555 certificate subject";
            string serviceNameStr = "555 Service";

            string profileId = "uddi:d1b9808e-a37e-430e-9ba9-326c0330ad2b";
            string profileName = "InvoiceProcessSimple";
            string profileId2 = "uddi:0b7c3880-62b4-41b8-a9f6-9cb44ebd9bb4";
            string profileName2 = "InvoiceProcessComplex";
            string endpointAddress = "http://example.org";
            string portTypeId = "uddi:2e0b402a-7a5e-476b-8686-b33f54fd1f47";
            string bindingReferenceId = "uddi:ee073296-bbc8-4d8f-8f27-841c26857d47";

            
            // ArsBusinessEntity
            ArsBusinessEntity arsBusinessEntity = GetArsBusinessEntity(cvr, name, description);
            arsBusinessEntity.Save();
            
            // Ars Endpoint
            ArsEndpoint arsEndPoint = GetArsEndPoint(cvr, certificateSubject, serviceNameStr, arsBusinessEntity);
            ArsEndpointSet endpointSet = arsBusinessEntity.Endpoints;
            endpointSet.Add(arsEndPoint);
            arsBusinessEntity.Endpoints = endpointSet;
            
            // Ars Process Instance
            ArsProcessInstanceSet arsProcessInstanceSet = new ArsProcessInstanceSet();
            ArsProcessInstance arsProcessInstance = GetProcessInstance(profileId, profileName);
            arsProcessInstance.Save();
            arsProcessInstanceSet.Add(arsProcessInstance);

            // ARS binding
            ArsBinding arsBinding = GetArsBinding(profileName, endpointAddress, portTypeId, bindingReferenceId, arsBusinessEntity, arsProcessInstanceSet);

            // Ars Binding Set
            ArsBindingSet arsBindingSet = new ArsBindingSet();
            arsBindingSet.Add(arsBinding);
            arsEndPoint.Bindings = arsBindingSet;
            
            arsEndPoint.Save();

            // Tilføje ny proces instans til binding
            ArsProcessInstance arsProcessInstance2 = GetProcessInstance(profileId2, profileName2);
            arsProcessInstance2.Save();
            arsProcessInstanceSet.Add(arsProcessInstance2);

            arsBinding.ProcessInstanceSet = arsProcessInstanceSet;

            arsEndPoint.Bindings = arsBindingSet;

            arsEndPoint.Save();
                        
            return arsBusinessEntity.ID.ID;
        }




        private static ArsBinding GetArsBinding(string profileName, string endpointAddress, string portTypeId, string bindingReferenceId, ArsBusinessEntity arsBusinessEntity, ArsProcessInstanceSet arsProcessInstanceSet) {
            OasisServiceSingleBindingRegistration serviceReference = new OasisServiceSingleBindingRegistration();
            serviceReference.Transport = new EndpointAddressType(EndpointAddressTypeCode.http);

            AccessPoint accessPoint = new AccessPoint(new Uri(endpointAddress));
            EndpointAddressType addressType = new EndpointAddressType(EndpointAddressTypeCode.http);
            UddiId businessKeyUddiId = arsBusinessEntity.ID;

            OasisBindingRegistrationReference bindingReference = new OasisBindingRegistrationReference();
            bindingReference.ID = new UddiGuidId(bindingReferenceId, true);

            OasisPortTypeRegistrationReference portTypeReference = new OasisPortTypeRegistrationReference();
            portTypeReference.ID = new UddiGuidId(portTypeId, true);

            serviceReference.BindingRegistrationRef = bindingReference;
            serviceReference.PortTypeRegistrationRef = portTypeReference;

            Description bindingDescription = new Description(profileName);

            ArsBinding arsBinding = new ArsBinding(arsProcessInstanceSet, serviceReference, accessPoint,
                addressType, bindingDescription, businessKeyUddiId, null);

            arsBinding.AccessPoint.AccessEndpointUri = new Uri(endpointAddress);
            return arsBinding;
        }

        private static ArsEndpoint GetArsEndPoint(string cvr, string certificateSubject, string serviceNameStr, ArsBusinessEntity arsBusinessEntity) {
            OIOTaxonomy oioTaxonomy = new OIOTaxonomy("OIO subject scheme / TRADE AND INDUSTRY / E-COMMERCE /", "uddi:ea4bc88f-9479-4f9b-a354-4acabdb99336");
            ArsEndpointKey endpointKey = new ArsEndpointKey(new IdentifierCvr(cvr));
            EndpointKeytype endpointKeytype = new EndpointKeytype(EndpointKeyTypeCode.cvr);
            EndpointCertificate endpointCertificate = new EndpointCertificate(certificateSubject);
            Name serviceName = new Name(serviceNameStr + " endpoint");
            Description serviceDescription = new Description("Endpoint til " + serviceNameStr);

            EndpointContactEmail endpointContactEmail = new EndpointContactEmail("");
            EndpointActivationDate endpointActivationDate = new EndpointActivationDate(DateTime.Now.AddDays(-2));
            EndpointExpirationDate endpointExpirationDate = new EndpointExpirationDate(DateTime.Now.AddYears(50));
            TermsOfUseUrl termsOfUseUrl = new TermsOfUseUrl();
            Version version = new Version("1.0.0");
            NewerVersionReference newerVersionReference = new NewerVersionReference();
            UddiId businessKey = arsBusinessEntity.ID;

            ArsEndpoint arsEndPoint = new ArsEndpoint(oioTaxonomy, endpointContactEmail, endpointKey,
                endpointKeytype, endpointActivationDate, endpointExpirationDate, termsOfUseUrl,
                endpointCertificate, version, newerVersionReference, serviceName,
                serviceDescription, businessKey);
            return arsEndPoint;
        }

        private static ArsBusinessEntity GetArsBusinessEntity(string cvr, string name, string description) {
            RegistrationConformanceClaim registrationConformanceClaim = new RegistrationConformanceClaim(RegistrationConformanceClaimCode.oiosi1_1);
            OIOTaxonomy oioTaxonomy = new OIOTaxonomy("OIO subject scheme / TRADE AND INDUSTRY / E-COMMERCE /", "uddi:ea4bc88f-9479-4f9b-a354-4acabdb99336");
            OrganizationKey key = new OrganizationKey(new IdentifierCvr(cvr));

            OrganizationKeyType organizationKeyType = new OrganizationKeyType(OrganizationKeyTypeCode.cvrNumber);
            UddiContactSimple businessEntityContact = new UddiContactSimple();
            businessEntityContact.PersonName = name;

            UddiDiscoveryUrl discoveryUrl = null;
            Name businessName = new Name(name);
            Description businessDescription = new Description(description);

            ArsBusinessEntity arsBusinessEntity = new ArsBusinessEntity();
            arsBusinessEntity.SetBusinessEntityDetails(registrationConformanceClaim,
                oioTaxonomy, key, organizationKeyType, businessEntityContact, discoveryUrl,
                businessName, businessDescription);
            return arsBusinessEntity;
        }

        private static ArsProcessInstance GetProcessInstance(string profileId, string profileName) {
            BusinessProcessRoleIdentifier roleIdentifier = new BusinessProcessRoleIdentifier();
            BusinessProcessRoleIdentifierType roleIdentifierType = new BusinessProcessRoleIdentifierType(BusinessProcessRoleIdentifierTypeCode.ubl2_0_ProcessRole);
            BusinessProcessDefinitionReference definitionReference =
                new BusinessProcessDefinitionReference(new UddiGuidId(profileId, true));
            Name instanceName = new Name(profileName);
            Description instanceDescription = new Description(profileName);
            DescriptionCollection instanceDescCollection = new DescriptionCollection(instanceDescription);

            ArsProcessInstance arsProcessInstance = new ArsProcessInstance(roleIdentifier,
                roleIdentifierType, definitionReference, instanceName, instanceDescCollection);
            arsProcessInstance.Save();
            return arsProcessInstance;
        }
    }
}
