from pathlib import Path
import io, json, hashlib, zipfile, subprocess, re
from pypdf import PdfReader, PdfWriter
from pypdf.generic import DecodedStreamObject, NameObject
from fontTools.ttLib import TTFont
from fontTools.pens.svgPathPen import SVGPathPen
from PIL import Image, ImageDraw, ImageFont
import cairosvg

ROOT=Path('/workspace/scratch/c66b757ea88e/TKOResearch-Logo-Package')
FONT=Path('/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf')
font=TTFont(FONT); glyphs=font.getGlyphSet(); cmap=font.getBestCmap(); upm=font['head'].unitsPerEm
def text_paths(size=88):
    x=0; parts=[]; previous=None; kern={}
    if 'kern' in font:
        for table in font['kern'].kernTables:kern.update(table.kernTable)
    for ch in 'TKOResearch':
        name=cmap[ord(ch)]
        if previous:x+=kern.get((previous,name),0)*size/upm
        pen=SVGPathPen(glyphs);glyphs[name].draw(pen)
        parts.append(f'<path transform="translate({x:.5f} 0) scale({size/upm:.8f} {-size/upm:.8f})" d="{pen.getCommands()}"/>')
        x+=font['hmtx'][name][0]*size/upm-2
        previous=name
    return ''.join(parts),x+2
TEXT,TW=text_paths()
def mark(primary,secondary):
    return f'''<path fill="{primary}" fill-rule="evenodd" d="M128 16A112 112 0 1 1 128 240A112 112 0 1 1 128 16ZM128 40A88 88 0 1 0 128 216A88 88 0 1 0 128 40Z"/>
    <g transform="translate(128 128) scale(.76) translate(-128 -128)">
    <path fill="{primary}" d="M69 75H148V101H119V183H91V101H69Z"/>
    <path fill="{secondary}" d="M119 119L165 75H198L150 127L200 183H166L119 137Z"/></g>'''
def svg(layout,treatment):
    p,s,bg={'color':('#16243A','#1B3A5B',None),'navy':('#16243A','#16243A',None),'black':('#000000','#000000',None),'white':('#FFFFFF','#FFFFFF',None),'inverse':('#FFFFFF','#FFFFFF','#16243A')}[treatment]
    m=mark(p,s)
    if layout=='mark':w=h=256;body=m
    elif layout=='horizontal':
        w=round(302+TW+30);h=256;body=m+f'<g fill="{p}" transform="translate(302 158)">{TEXT}</g>'
    elif layout=='stacked':
        w=round(TW+64);h=405;body=f'<g transform="translate({(w-256)/2} 20)">{m}</g><g fill="{p}" transform="translate(32 357)">{TEXT}</g>'
    else:w=round(TW+48);h=128;body=f'<g fill="{p}" transform="translate(24 95)">{TEXT}</g>'
    background=f'<rect width="{w}" height="{h}" fill="{bg}"/>' if bg else ''
    return f'<svg xmlns="http://www.w3.org/2000/svg" width="{w}" height="{h}" viewBox="0 0 {w} {h}" role="img" aria-label="TKOResearch {layout} logo"><title>TKOResearch</title>{background}{body}</svg>',w,h

for folder in ['vector','online/png','online/icons','print/pdf-rgb','print/pdf-cmyk','print/eps-cmyk','previews','source']: (ROOT/folder).mkdir(parents=True,exist_ok=True)
for layout in ['mark','horizontal','stacked','wordmark']:
    for treatment in ['color','navy','black','white','inverse']:
        data,w,h=svg(layout,treatment);stem=f'TKOResearch-{layout}-{treatment}'
        (ROOT/'vector'/f'{stem}.svg').write_text(data)
        pdf=ROOT/'print/pdf-rgb'/f'{stem}.pdf';cairosvg.svg2pdf(bytestring=data.encode(),write_to=str(pdf))
        cmyk=ROOT/'print/pdf-cmyk'/f'{stem}.pdf'
        subprocess.run(['gs','-q','-dBATCH','-dNOPAUSE','-sDEVICE=pdfwrite','-sColorConversionStrategy=CMYK','-dProcessColorModel=/DeviceCMYK','-dCompatibilityLevel=1.4',f'-sOutputFile={cmyk}',str(pdf)],check=True)
        if treatment=='black':
            reader=PdfReader(cmyk);page=reader.pages[0];stream=DecodedStreamObject()
            stream.set_data(re.sub(rb'(?:[0-9.]+\s+){4}k\b',b'0 0 0 1 k',page.get_contents().get_data()))
            page[NameObject('/Contents')]=stream;writer=PdfWriter();writer.add_page(page)
            with cmyk.open('wb') as f:writer.write(f)
        subprocess.run(['pdftops','-eps',str(cmyk),str(ROOT/'print/eps-cmyk'/f'{stem}.eps')],check=True)
        sizes=[256,512,1024,2048] if layout=='mark' else [512,1024,2048,4096]
        for size in sizes:
            cairosvg.svg2png(bytestring=data.encode(),output_width=size,output_height=round(size*h/w),write_to=str(ROOT/'online/png'/f'{stem}-{size}px.png'))
        # Large print raster, 300 ppi metadata. Vector files remain preferred.
        png=Image.open(io.BytesIO(cairosvg.svg2png(bytestring=data.encode(),output_width=3000,output_height=round(3000*h/w))))
        (ROOT/'print/png-300ppi').mkdir(exist_ok=True)
        png.save(ROOT/'print/png-300ppi'/f'{stem}-3000px.png',dpi=(300,300))

data,_,_=svg('mark','color');icons=ROOT/'online/icons'
for size in [16,24,32,48,64,128,180,192,256,512]:
    cairosvg.svg2png(bytestring=data.encode(),output_width=size,output_height=size,write_to=str(icons/f'icon-{size}.png'))
Image.open(icons/'icon-256.png').save(icons/'favicon.ico',sizes=[(16,16),(32,32),(48,48),(64,64),(128,128),(256,256)])
(icons/'favicon.svg').write_text(data)
for size,name in [(180,'apple-touch-icon.png'),(192,'android-chrome-192x192.png'),(512,'android-chrome-512x512.png')]:
    im=Image.open(icons/f'icon-{size}.png').convert('RGBA');back=Image.new('RGBA',im.size,'#F5F3EE');back.alpha_composite(im);back.convert('RGB').save(icons/name)
(icons/'site.webmanifest').write_text(json.dumps({'name':'TKOResearch','short_name':'TKOResearch','icons':[{'src':'android-chrome-192x192.png','sizes':'192x192','type':'image/png'},{'src':'android-chrome-512x512.png','sizes':'512x512','type':'image/png'}],'theme_color':'#16243A','background_color':'#F5F3EE','display':'standalone'},indent=2))
preview=Image.new('RGB',(1600,1100),'#F5F3EE');d=ImageDraw.Draw(preview);label=ImageFont.truetype(str(FONT),24)
d.text((60,35),'TKOResearch | Refined identity',font=label,fill='#16243A')
for layout,treatment,x,y,width in [('horizontal','color',60,110,1200),('mark','color',70,440,280),('stacked','navy',420,410,500),('horizontal','black',70,850,690),('horizontal','white',830,850,690)]:
    data,w,h=svg(layout,treatment);im=Image.open(io.BytesIO(cairosvg.svg2png(bytestring=data.encode(),output_width=width,output_height=round(width*h/w)))).convert('RGBA')
    if treatment=='white':d.rectangle((800,810,1570,1080),fill='#16243A')
    preview.paste(im,(x,y),im)
for i,size in enumerate([16,24,32,40,64]):
    im=Image.open(icons/f'icon-{size}.png') if (icons/f'icon-{size}.png').exists() else Image.open(io.BytesIO(cairosvg.svg2png(bytestring=svg('mark','color')[0].encode(),output_width=size,output_height=size)))
    preview.paste(im,(1040+i*100,530),im);d.text((1040+i*100,625),str(size),fill='#16243A',font=label)
preview.save(ROOT/'previews/TKOResearch-logo-preview.png')
(ROOT/'README.md').write_text('''# TKOResearch refined logo package

Revision: 2026-10-01. Based on the existing September 2026 TK-in-O identity.

Changes: removed inner ring and red tab, reduced the original TK shapes to 76% around their center for clearance, preserved navy/blue colors and bold DejaVu Sans wordmark, removed the narrow AI-security tagline. No website or repository files were changed.

## Choose a file
- vector/: editable scalable SVG masters. All lettering is outlined; no font installation needed.
- online/png/: transparent color, navy, black and white; inverse includes a navy background. Mark widths: 256/512/1024/2048 px. Other layouts: 512/1024/2048/4096 px.
- online/icons/: favicon ICO and SVG, PNG sizes 16–512, opaque Apple/Android icons, web manifest. Adjust manifest paths to your deployment.
- print/pdf-rgb/: vector PDFs for digital documents and RGB workflows.
- print/pdf-cmyk/ and print/eps-cmyk/: vector process-CMYK exports, not spot-color separations or PDF/X-certified files. Confirm color with your printer and request a proof for the chosen paper/press; these use the renderer's default process conversion, not a custom press profile.
- print/png-300ppi/: 3000-px raster exports tagged 300 ppi (10 inches wide); use vector artwork for larger output.
- previews/: visual reference, not production artwork.
- source/: original reference SVGs, build script, font license.

## Treatments
color = navy #16243A with blue #1B3A5B K; navy = single-color #16243A; black = solid #000; white = solid white on transparency; inverse = white on navy. Black/white contain no gray fills. Full-color blue/navy differentiation is subtle by design; the mark also works in one color.

## Usage
Prefer horizontal for website headers and documents; stacked for centered covers; mark for avatars/icons; wordmark when space is tight. White artwork is invisible on white, so use on dark backgrounds. Preserve proportions and allow at least one ring thickness of clear space around the visible mark. Suggested minimum display: mark 24 px (16 px supplied for favicons), horizontal 180 px wide, stacked 160 px wide. Suggested print minimum: mark 8 mm, horizontal 45 mm. These are design guidelines, not measured recognition thresholds.

SVG/PDF masters have clean transparent space outside artwork except inverse. EPS does not support alpha transparency but contains no painted background for transparent treatments. Use SVG/PNG/PDF if actual transparency is required. Printer bleed depends on the document, not the standalone logo.

This is an evolutionary logo refinement, not a trademark availability or legal clearance review.
''')
for src in Path('/tmp/tko-review').glob('brand_vector_TKOResearch*svg'):(ROOT/'source'/src.name).write_bytes(src.read_bytes())
(ROOT/'source/build_logo.py').write_bytes(Path(__file__).read_bytes())
license_path=Path('/usr/share/doc/fonts-dejavu-core/copyright')
if license_path.exists():(ROOT/'source/font-license.txt').write_bytes(license_path.read_bytes())
manifest=[]
for p in sorted(ROOT.rglob('*')):
    if p.is_file() and p.name!='manifest.json':manifest.append({'path':str(p.relative_to(ROOT)),'bytes':p.stat().st_size,'sha256':hashlib.sha256(p.read_bytes()).hexdigest()})
(ROOT/'manifest.json').write_text(json.dumps(manifest,indent=2))
zip_path=ROOT.with_suffix('.zip')
with zipfile.ZipFile(zip_path,'w',zipfile.ZIP_DEFLATED) as z:
    for p in sorted(ROOT.rglob('*')):
        if p.is_file():z.write(p,str(p.relative_to(ROOT.parent)))
print(json.dumps({'zip':str(zip_path),'bytes':zip_path.stat().st_size,'files':len(manifest)+1}))
