text: from autosar.writer.writer_base import BaseWriter
  from autosar.writer.package_writer import PackageWriter
  from autosar.base import applyFilter
  import collections
  
  class WorkspaceWriter(BaseWriter):
      def __init__(self, version, patch, schema, packageWriter):
          super().__init__(version, patch)
          assert(isinstance(packageWriter, PackageWriter))
          self.schema = schema
          self.packageWriter=packageWriter
  
      def beginFile(self):
          lines=[]
          if (self.version >= 3.0) and (self.version < 4.0):
              lines.append('<?xml version="1.0" encoding="UTF-8"?>')
              versionString = "%d.%d.%d"%(self.major, self.minor, self.patch)
              if self.schema is None:
                  schema = 'autosar_'+versionString+'.xsd'
              else:
                  schema = self.schema
              lines.append('<AUTOSAR xsi:schemaLocation="http://autosar.org/%s %s" xmlns="http://autosar.org/%s" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'%(versionString, schema, versionString))
              lines.append(self.indentChar+'<TOP-LEVEL-PACKAGES>')
          elif self.version >= 4.0:
              lines.append('<?xml version="1.0" encoding="utf-8"?>')
              lines.append('<AUTOSAR xmlns="http://autosar.org/schema/r4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://autosar.org/schema/r4.0 AUTOSAR_{0}-{1}-{2}.xsd">'.format(self.major, self.minor, self.patch))
              lines.append(self.indentChar+'<AR-PACKAGES>')
          return lines
  
      def endFile(self):
          lines=[]
          if (self.version >= 3.0) and (self.version<4.0):
              lines.append(self.indentChar+'</TOP-LEVEL-PACKAGES>')
          else:
              lines.append(self.indentChar+'</AR-PACKAGES>')
          lines.append('</AUTOSAR>')
          return lines
  
  
      def saveXML(self, ws, fp, filters, ignore):
          fp.write(self.toXML(ws, filters, ignore))
  
      def toXML(self, ws, filters, ignore):
          lines=self.beginFile()
          result='\n'.join(lines)+'\n'
          for package in ws.packages:
              if applyFilter(package.ref, filters):
                  lines=self.packageWriter.toXML(package, filters, ignore)
                  if len(lines)>0:
                      lines=self.indent(lines,2)
                      result+='\n'.join(lines)+'\n'
              ws.unhandledWriter = ws.unhandledWriter.union(package.unhandledWriter)
          lines=self.endFile()
          return result+'\n'.join(lines)+'\n'
  
      def toCode(self, ws, filters=None, ignore=None, head=None, tail=None, isModule=False, isTemplate=False, indent=3):
          localvars = collections.OrderedDict()
          localvars['ws']=ws
          indentStr=indent*' '
          if isModule == False:
              #head
              if head is None:
                  lines=['import autosar']
                  if not isTemplate:
                      lines.append('ws=autosar.workspace()')
                  result='\n'.join(lines)+'\n\n'
              else:
                  if isinstance(head,list):
                      head = '\n'.join(head)
                  assert(isinstance(head,str))
                  result = head+'\n\n'
  
  
              #body
              for package in ws.packages:
                  if applyFilter(package.ref, filters):
                      lines=self.packageWriter.toCode(package, filters, ignore, localvars, isTemplate)
                      if len(lines)>0:
                          result+='\n'.join(lines)+'\n'
              #tail
              if not isTemplate:
                  if tail is None:
                      result+='\n'+'print(ws.toXML())\n'
                  else:
                      if isinstance(tail,list):
                          tail = '\n'.join(tail)
                      assert(isinstance(tail,str))
                      result+='\n'+tail
              return result
          else:
              if head is None:
                  head=[
                     ['import autosar'],
                     ['ws = autosar.workspace()']
                  ]
              if len(head)!=2:
                  raise ValueError('when module=True then head must have exactly two elements (list of lists)')
              if isinstance(head[0], collections.Iterable):
                  head[0] = '\n'.join(head[0])
              assert(isinstance(head[0],str))
              result = head[0]+'\n\n'
              #body
              result+='def apply(ws):\n'
              for package in ws.packages:
                  if applyFilter(package.ref, filters):
                      lines=self.packageWriter.toCode(package, filters, ignore, localvars, isTemplate)
                      if len(lines)>0:
                          lines=[indentStr+x for x in lines]
                          result+='\n'.join(lines)+'\n'
  
              #tail
              result+="\nif __name__=='__main__':\n"
              if isinstance(head[1], collections.Iterable):
                  head[1] = '\n'.join([indentStr+x for x in head[1]])
              else:
                  head[1] = '\n'.join([indentStr+x for x in head[1].split('\n')])
              assert(isinstance(head[1],str))
              result+=head[1]+'\n'
              result+=indentStr+'apply(ws)\n'
              if not isTemplate:
                  if tail is None:
                      result+=indentStr+'print(ws.toXML())\n'
                  else:
                      if isinstance(tail,list):
                          tail = '\n'.join([indentStr+x for x in tail])
                      else:
                          tail = '\n'.join([indentStr+x for x in tail.split('\n')])
                      assert(isinstance(tail,str))
                      result+=tail+'\n'
              return result
  
      def saveCode(self, ws, fp, filters=None, ignore=None, head=None, tail=None, isModule=False, isTemplate=False):
          fp.write(self.toCode(ws, filters, ignore, head, tail, isModule, isTemplate))
  