from org.codehaus.jettison.json import JSONObject, JSONArray
import sys;
from WASConfLog import Log;
from Property import Property
from utilities import Util

__name_att__ = None;

def _export(serverobjid, serverrespath, dynamicClusterServerTemplate = 0):
  #Check to make sure that it is okay for server to belong to a coregroup.
  servertype = Util.getRequiredAttribute(serverobjid, 'serverType', 'Server');
  if servertype == "WEB_SERVER":
    return;

  Util.pushPathElement('CoreGroupMapping')

  cmgFoldName = Util.getTypeFoldername("CoreGroupMapping");
  folpath = "%(cur)s/%(fol)s" % { 'cur':serverrespath, 'fol': cmgFoldName};

  folderObject = JSONObject();
  folderObject.put("name", cmgFoldName);
  folderObject.put("path", folpath);
  folderObject.put("teamMappings", JSONArray());
  folderObject.put("inheritTeam", "true");
  folderObject.put("description", "Discovered WebSphereCoreGroupMapping");

  respath = "%(cur)s/%(res)s" % { 'cur':folpath, 'res':cmgFoldName };

  exportedObject = JSONObject();
  exportedObject.put("name", cmgFoldName);
  exportedObject.put("path", respath);
  exportedObject.put("teamMappings", JSONArray());
  exportedObject.put("inheritTeam", "true");
  exportedObject.put("description", "Discovered WebSphereCoreGroupMapping");
  exportedObject.put("roleName", "WebSphereCoreGroupMapping");
  roleProperties = JSONObject();
  exportedObject.put("roleProperties", roleProperties);

  typeFolders = {};
  extraObjects = [];

  cgAndCgs = None;
  if dynamicClusterServerTemplate == 0:
    cgAndCgs = findCoreGroupAndCoreGroupServerForServer(serverobjid);
    if cgAndCgs is None:
      raise Exception("CoreGroupServer not found for server " + serverobjid);
  else:
    Util.popPathElement('CoreGroupMapping');
    return;
  cg = cgAndCgs['coreGroup'];
  cgs = cgAndCgs['coreGroupServer'];
  cgname = Util.getRequiredAttribute(cg, 'name', 'CoreGroup');
  preferredServers = Util.getOptionalAttribute(cg, 'preferredCoordinatorServers', 'CoreGroup');
  preferred = 'false';
  if preferredServers.find(cgs) != -1:
    preferred = 'true';

  extraObjects = Property.exportProperties(cgs,respath,extraObjects,typeFolders,'customProperties',"CoreGroupServer");
  extraObjects.append(folderObject);

  roleProperties.put("websphere.coregroupmapping.coregroupname", cgname);
  roleProperties.put("websphere.coregroupmapping.preferred", preferred);

  policies = Util.parseConfigIdListAttribute(cg, 'policies', 'CoreGroup');
  for policy in policies:
    policyType = getPolicyType(policy);
    if policyType is not None:
      policyServer = "";
      if policyType == 'StaticPolicy':
        policyServers = Util.getOptionalAttribute(policy, 'servers', 'StaticPolicy');
      else:
        policyServers = Util.getOptionalAttribute(policy, 'preferredServers', policyType);
      if policyServers.find(cgs) != -1:
        policyObject = JSONObject();
        extraObjects.append(policyObject);
        folder = Util.createTypeFolder(respath, 'PolicyRef', typeFolders);
        if folder.has_key('object'):
          extraObjects.append(folder['object']);
        foldpath = folder['path'];
        polRefName = Util.getRequiredAttribute(policy, 'name', policyType);
        polRefPath = "%(cur)s/%(name)s" % { 'cur': foldpath, 'name': polRefName };
        policyObject.put('name', polRefName);
        policyObject.put('path', polRefPath);
        policyObject.put('description', 'Discovered Policy');
        policyObject.put("teamMappings", JSONArray());
        policyObject.put("inheritTeam", "true");
        policyObject.put("roleName", "WebSpherePolicyRef");
        polRoleProps = JSONObject();
        policyObject.put("roleProperties", polRoleProps);
        polRoleProps.put('websphere.policyref.policyname', polRefName);
        polRoleProps.put('websphere.policyref.policytype', policyType);

  result = { 'object': exportedObject, 'respath':respath }
  if len(extraObjects) != 0:
    result['extraObjects'] = extraObjects;
  Util.popPathElement('CoreGroupMapping');
  return result;

def doImport(parentid, jsonobject):
  Util.pushPathElement('CoreGroupMapping')
  
  if not jsonobject.has("roleProperties"):
    raise Exception("CoreGroupMapping resource has no role properties!");

  roleProperties = jsonobject.getJSONObject("roleProperties");
  cgname = roleProperties.getString("websphere.coregroupmapping.coregroupname");
  correctcg = Util.getid("/CoreGroup:%s/" % cgname);
  if correctcg is None or len(correctcg) < 1:
    raise Exception("Could not find CoreGroup with name %(name)s specified for Server %(id)s" % { 'name':cgname, 'id':parentid });

  preferred = roleProperties.optString("websphere.coregroupmapping.preferred", "false");
  cgAndCgs = findCoreGroupAndCoreGroupServerForServer(parentid);
  serverName = Util.getRequiredAttribute(parentid, 'name', 'Server');
  nodeName = getNodeName(parentid);
  if cgAndCgs is None:
     #this is probably not possible(hopefully not possible)
    props = [];
    props.append(['serverName', serverName]);
    props.append(['nodeName', nodeName]);
    cgs = Util.create('CoreGroupServer', correctcg, props, 'coreGroupServers');
  else:
    cg = cgAndCgs['coreGroup'];
    cgs = cgAndCgs['coreGroupServer'];
    wrongcgname = Util.getRequiredAttribute(cg, 'name', 'CoreGroup');
    if wrongcgname != cgname:
      clusterForServer = Util.getClusterNameForServer(serverName, nodeName);
      if clusterForServer is not None and len(clusterForServer) > 0:
        Util.moveClusterToCoreGroup(clusterForServer, wrongcgname, cgname);
      else:
        try:
          Util.moveServerToCoreGroup(serverName, nodeName, wrongcgname, cgname)
        except:
          clusterForServer = Util.getRequiredAttribute(parentid, 'clusterName', 'Server');
          if clusterForServer is not None and len(clusterForServer) > 0:
            Util.moveClusterToCoreGroup(clusterForServer, wrongcgname, cgname);
          else:
            raise sys.exc_info()[1]; #reraise the expcetion

  cgAndCgs = findCoreGroupAndCoreGroupServerForServer(parentid);
  cg = cgAndCgs['coreGroup'];
  cgs = cgAndCgs['coreGroupServer'];
  if preferred == "true":
    #make sure this is a preferred server on the correct cg
    curPreferredServers = Util.getOptionalAttribute(correctcg, 'preferredCoordinatorServers', 'CoreGroup');
    if curPreferredServers.find(cgs) == -1:
      #this modify does an "ADD" in websphere for some unknown reason.
      Util.modify(correctcg, [['preferredCoordinatorServers', cgs]], 1);

  if jsonobject.has("children"):
    children = Util.getHighestChildrenWithRole(jsonobject.getJSONArray('children'));
    for curjsonobject in children[:]:
      currole = curjsonobject.getString("roleName");
      propertyObject = Property.createObjIfRole(cgs, curjsonobject, currole);
      if currole == "WebSpherePolicyRef":
        #we know that the current cgs cannot be associated with ANY Policies
        polRoleProperties = curjsonobject.getJSONObject("roleProperties");
        polName = polRoleProperties.getString("websphere.policyref.policyname");
        polType = polRoleProperties.getString("websphere.policyref.policytype")
        Util.pushPathElement('PolicyRef');
        addCGSToPolicy(polName, polType, correctcg, cgs);
        Util.popPathElement('PolicyRef');

  Util.popPathElement('CoreGroupMapping');
  return cgs;

def addCGSToPolicy(polName, polType, cg, cgs):
  policy = getPolicyForCG(polName, polType, cg);
  if policy is None or len(policy) < 1:
    raise Exception("CoreGroupServer[%(cgs)s] defined to be part of %(type)s[%(pol)s] on CoreGroup[%(cg)s] which is not found." % { 'cgs':cgs, 'cg':cg, 'pol':polName, 'type':polType });
  if polType == "StaticPolicy":
    attName = 'servers';
  else:
    attName = 'preferredServers';
  Util.modify(policy, [[attName, cgs]]);

def getPolicyForCG(polName, polType, cg):
  policies = Util.parseConfigIdListAttribute(cg, 'policies', 'CoreGroup');
  policy = None;
  for pol in policies:
    curpoltype = getPolicyType(pol);
    if curpoltype is not None and curpoltype == polType:
      curpolname = Util.getRequiredAttribute(pol, 'name', curpoltype);
      if curpolname == polName:
        policy = pol;
        break;
  return policy;

def getPolicyType(policy):
  policyType = None;
  if policy.find('#MOfNPolicy_') != -1:
    policyType = 'MOfNPolicy';
  elif policy.find('#OneOfNPolicy_') != -1:
    policyType = 'OneOfNPolicy';
  elif policy.find('#StaticPolicy_') != -1:
    policyType = 'StaticPolicy';
  elif policy.find('#PreferredServerPolicy_') != -1:
    policyType = 'PreferredServerPolicy';
  return policyType;

def findCoreGroupAndCoreGroupServerForServer(serid):
  nodeName = getNodeName(serid);
  serverName = Util.getRequiredAttribute(serid, 'name', 'Server');
  coreGroups = Util.getAssociatedObjects(None, 'CoreGroup', 1);
  if coreGroups is not None and len(coreGroups) > 0:
    for cg in coreGroups:
      for cgs in Util.parseConfigIdListAttribute(cg, 'coreGroupServers', 'CoreGroup'):
        cgsname = Util.getRequiredAttribute(cgs, 'serverName', 'CoreGroupServer');
        cgsnodename = Util.getRequiredAttribute(cgs, 'nodeName', 'CoreGroupServer');
        if cgsname == serverName and nodeName == cgsnodename:
          result = {'coreGroup':cg, 'coreGroupServer':cgs};
          return result;
  return None;


def getNodeName(serid):
  return Util.getNodeName(serid);
